### Quick Start: Add and Install Plugin Source: https://github.com/can1357/oh-my-pi/blob/main/docs/marketplace.md Use these commands to quickly add a marketplace source and install a plugin. ```bash /marketplace add anthropics/claude-plugins-official /marketplace install wordpress.com@claude-plugins-official ``` -------------------------------- ### Quick Start Extension Example Source: https://github.com/can1357/oh-my-pi/blob/main/docs/extensions.md A comprehensive example demonstrating common extension functionalities including setting a label, handling session start events, blocking specific tool calls, registering a custom tool, and registering a command. ```typescript import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent"; import { Type } from "@sinclair/typebox"; export default function (pi: ExtensionAPI) { pi.setLabel("Safety + Utilities"); pi.on("session_start", async (_event, ctx) => { ctx.ui.notify(`Extension loaded in ${ctx.cwd}`, "info"); }); pi.on("tool_call", async (event) => { if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) { return { block: true, reason: "Blocked by extension policy" }; } }); pi.registerTool({ name: "hello_extension", label: "Hello Extension", description: "Return a greeting", parameters: Type.Object({ name: Type.String() }), async execute(_toolCallId, params, _signal, _onUpdate, _ctx) { return { content: [{ type: "text", text: `Hello, ${params.name}` }], details: { greeted: params.name }, }; }, }); pi.registerCommand("hello-ext", { description: "Show queue state", handler: async (_args, ctx) => { ctx.ui.notify(`pending=${ctx.hasPendingMessages()}`, "info"); }, }); } ``` -------------------------------- ### Plugin Spec Grammar Examples Source: https://github.com/can1357/oh-my-pi/blob/main/docs/plugin-manager-installer-plumbing.md Demonstrates the supported syntax for specifying packages and their features in plugin installation. ```text pkg pkg[*] pkg[] pkg[a,b] @scope/pkg@1.2.3[feat] ``` -------------------------------- ### Install @oh-my-pi/pi-coding-agent Source: https://github.com/can1357/oh-my-pi/blob/main/docs/sdk.md Install the SDK package using Bun. ```bash bun add @oh-my-pi/pi-coding-agent ``` -------------------------------- ### Create File Example Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/prompts/tools/patch.md Example of creating a new file named 'hello.txt' with the content 'Hello\n'. ```bash edit {"path":"hello.txt","edits":[{"op":"create","diff":"Hello\n"}]} ``` -------------------------------- ### Run Minimal Example Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/sdk/README.md Execute the minimal TypeScript example for the SDK. ```bash cd packages/coding-agent npx tsx examples/sdk/01-minimal.ts ``` -------------------------------- ### Quick Start Agent Session Source: https://github.com/can1357/oh-my-pi/blob/main/docs/sdk.md Create an agent session with default auto-discovery settings and subscribe to message updates. This is a minimal setup for immediate use. ```typescript import { createAgentSession } from "@oh-my-pi/pi-coding-agent"; const { session, modelFallbackMessage } = await createAgentSession(); if (modelFallbackMessage) { process.stderr.write(`${modelFallbackMessage}\n`); } const unsubscribe = session.subscribe((event) => { if ( event.type === "message_update" && event.assistantMessageEvent.type === "text_delta" ) { process.stdout.write(event.assistantMessageEvent.delta); } }); await session.prompt("Summarize this repository in 3 bullets."); unsubscribe(); await session.dispose(); ``` -------------------------------- ### Install @oh-my-pi/pi-ai Source: https://github.com/can1357/oh-my-pi/blob/main/packages/ai/README.md Install the library using npm. ```bash npm install @oh-my-pi/pi-ai ``` -------------------------------- ### Rename File Example Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/prompts/tools/patch.md Example of updating 'src/app.py' and renaming it to 'src/main.py' simultaneously. The diff content is minimal in this example. ```bash edit {"path":"src/app.py","edits":[{"op":"update","rename":"src/main.py","diff":"@@\n …\n"}]} ``` -------------------------------- ### Marketplace Install Commands Source: https://github.com/can1357/oh-my-pi/blob/main/docs/skills/authoring-marketplaces.md Commands to install plugins from a marketplace. Use `--force` to reinstall or `--scope project` for project-specific installations. ```bash /marketplace install name@marketplace-name ``` ```bash /marketplace install --force name@marketplace-name # reinstall ``` ```bash /marketplace install --scope project name@marketplace # project-scoped ``` -------------------------------- ### Add and Install Marketplace Plugin Source: https://github.com/can1357/oh-my-pi/blob/main/docs/skills/examples/mini-marketplace/README.md Use these commands to add the mini-marketplace to your system and then install the 'my-plugin' from it. The CLI commands provide an alternative way to achieve the same. ```bash /marketplace add ./docs/skills/examples/mini-marketplace /marketplace install my-plugin@example-marketplace ``` ```bash omp plugin marketplace add ./docs/skills/examples/mini-marketplace omp plugin install my-plugin@example-marketplace ``` -------------------------------- ### Full marketplace.json Example Source: https://github.com/can1357/oh-my-pi/blob/main/docs/skills/authoring-marketplaces.md A comprehensive `marketplace.json` example including schema, owner details, description, and multiple plugins with different source types. ```json { "$schema": "https://anthropic.com/claude-code/marketplace.schema.json", "name": "acme-plugins", "owner": { "name": "Acme Corp", "email": "plugins@acme.example" }, "description": "Official Acme plugins for oh-my-pi", "plugins": [ { "name": "acme-linter", "description": "Enforce Acme coding standards", "category": "development", "source": "./plugins/linter" }, { "name": "acme-deploy", "description": "One-command deploy to Acme cloud", "category": "devops", "source": { "source": "github", "repo": "acme-corp/omp-deploy-plugin", "ref": "main" } } ] } ``` -------------------------------- ### Install Marketplace Plugins Source: https://github.com/can1357/oh-my-pi/blob/main/docs/skills/authoring-marketplaces.md Commands to add a marketplace to Claude and install a specific plugin from it. ```bash /marketplace add your-github-username/my-marketplace /marketplace install my-plugin@my-marketplace ``` -------------------------------- ### Install oh-my-pi via Installer Script Source: https://context7.com/can1357/oh-my-pi/llms.txt Installs oh-my-pi using a provided script for Linux and macOS. Supports installing a specific release tag via binary. ```bash curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh ``` ```bash curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | \ sh -s -- --binary --ref v3.20.1 ``` -------------------------------- ### Install @oh-my-pi/pi-agent Source: https://github.com/can1357/oh-my-pi/blob/main/packages/agent/README.md Install the agent package using npm. ```bash npm install @oh-my-pi/pi-agent ``` -------------------------------- ### Initialize and Start TUI Application Source: https://github.com/can1357/oh-my-pi/blob/main/packages/tui/README.md Demonstrates how to instantiate a ProcessTerminal, initialize the TUI, add components, and start the application loop. ```typescript import { TUI, Text, Editor, ProcessTerminal } from "@oh-my-pi/pi-tui"; const terminal = new ProcessTerminal(); const tui = new TUI(terminal); tui.addChild(new Text("Welcome to my app!")); const editor = new Editor(editorTheme); editor.onSubmit = (text) => { console.log("Submitted:", text); tui.addChild(new Text(`You said: ${text}`)); }; tui.addChild(editor); tui.start(); ``` -------------------------------- ### Basic Oh My Pi Usage Examples Source: https://github.com/can1357/oh-my-pi/blob/main/README.md Provides examples for common 'omp' command usages, including interactive mode, non-interactive prompts, continuing sessions, and resuming by ID. ```bash # Interactive mode omp ``` ```bash # Non-interactive omp -p "List all .ts files in src/" omp -c "What did we discuss?" ``` ```bash # Resume by ID prefix omp -r abc123 ``` -------------------------------- ### Install Oh My Pi via Mise Source: https://github.com/can1357/oh-my-pi/blob/main/README.md Installs Oh My Pi using the mise version manager by referencing its GitHub repository. ```bash mise use -g github:can1357/oh-my-pi ``` -------------------------------- ### Install oh-my-pi via Bun Source: https://context7.com/can1357/oh-my-pi/llms.txt Installs the oh-my-pi agent globally using the Bun package manager. Recommended for most users. ```bash bun install -g @oh-my-pi/pi-coding-agent ``` -------------------------------- ### models.yml - Full Provider Configuration Example Source: https://github.com/can1357/oh-my-pi/blob/main/docs/models.md Example of a custom provider configuration including base URL, API key, model definitions, and compatibility settings. ```yaml providers: my-provider: baseUrl: https://api.example.com/v1 apiKey: MY_PROVIDER_API_KEY api: openai-completions headers: X-Team: platform authHeader: true auth: apiKey disableStrictTools: false # set true for Anthropic-compatible endpoints that reject the strict field discovery: type: ollama modelOverrides: some-model-id: name: Renamed model models: - id: some-model-id name: Some Model api: openai-completions reasoning: false input: [text] cost: input: 0 output: 0 cacheRead: 0 cacheWrite: 0 contextWindow: 128000 maxTokens: 16384 headers: X-Model: value compat: supportsStore: true supportsDeveloperRole: true supportsReasoningEffort: true maxTokensField: max_completion_tokens openRouterRouting: only: [anthropic] vercelGatewayRouting: order: [anthropic, openai] extraBody: gateway: m1-01 controller: mlx ``` -------------------------------- ### Minimal Controlled Embed Example Source: https://github.com/can1357/oh-my-pi/blob/main/docs/sdk.md This example demonstrates how to create an agent session with specific settings and tools, subscribe to message updates, and prompt the agent. Ensure all necessary imports are available. ```typescript import { createAgentSession, discoverAuthStorage, ModelRegistry, SessionManager, Settings, } from "@oh-my-pi/pi-coding-agent"; const authStorage = await discoverAuthStorage(); const modelRegistry = new ModelRegistry(authStorage); await modelRegistry.refresh(); const settings = Settings.isolated({ "compaction.enabled": true, "retry.enabled": true, }); const { session } = await createAgentSession({ authStorage, modelRegistry, settings, sessionManager: SessionManager.inMemory(), toolNames: ["read", "grep", "find", "edit", "write"], enableMCP: false, enableLsp: true, }); session.subscribe((event) => { if ( event.type === "message_update" && event.assistantMessageEvent.type === "text_delta" ) { process.stdout.write(event.assistantMessageEvent.delta); } }); await session.prompt("Find all TODO comments in this repo and propose fixes."); await session.dispose(); ``` -------------------------------- ### RPC Protocol: Sending Commands Source: https://context7.com/can1357/oh-my-pi/llms.txt Examples of JSON messages to send to the RPC server via stdin. These include starting prompts, queuing follow-ups, getting state, changing models, and registering host tools. ```json { "id": "req_1", "type": "prompt", "message": "Summarize this repo in 3 bullets" } ``` ```json { "id": "req_2", "type": "prompt", "message": "Focus on the Rust crates", "streamingBehavior": "followUp" } ``` ```json { "id": "req_3", "type": "get_state" } ``` ```json { "id": "req_4", "type": "set_model", "provider": "anthropic", "modelId": "claude-sonnet-4-5" } ``` ```json { "id": "req_5", "type": "set_host_tools", "tools": [ { "name": "echo_host", "label": "Echo Host", "description": "Echo a value from the embedding host", "parameters": { "type": "object", "properties": { "message": { "type": "string" } }, "required": ["message"], "additionalProperties": false } ] } ``` ```json { "id": "req_6", "type": "compact", "customInstructions": "Focus on API changes" } ``` -------------------------------- ### Environment and Header Variable Resolution Examples Source: https://github.com/can1357/oh-my-pi/blob/main/docs/mcp-config.md Examples demonstrating how OMP resolves environment and header values. Values starting with '!' are treated as shell commands. Other values are checked against environment variables. ```json { "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "GITHUB_PERSONAL_ACCESS_TOKEN" }, "headers": { "X-MCP-Insiders": "true" } } ``` -------------------------------- ### Startup Command Source: https://github.com/can1357/oh-my-pi/blob/main/docs/rpc.md How to start the Oh My Pi agent in RPC mode. ```APIDOC ## Startup ```bash omp --mode rpc [regular CLI options] ``` Behavior notes: - `@file` CLI arguments are rejected in RPC mode. - RPC mode disables automatic session title generation by default to avoid an extra model call. - RPC mode resets workflow-altering `todo.*`, `task.*`, `async.*`, and `bash.autoBackground.*` settings to their built-in defaults instead of inheriting user overrides. - The process reads stdin as JSONL (`readJsonl(Bun.stdin.stream())`). - At startup it writes `{ "type": "ready" }` before processing commands. - When stdin closes, pending host-tool calls are rejected and the process exits with code `0`. - Responses/events are written as one JSON object per line. ``` -------------------------------- ### Multi-Provider Conversation Handoff Example Source: https://github.com/can1357/oh-my-pi/blob/main/packages/ai/README.md Demonstrates a conversation that starts with Claude, switches to GPT-5, and then to Gemini. The library automatically transforms messages for compatibility between providers. ```typescript import { getModel, complete, Context } from "@oh-my-pi/pi-ai"; // Start with Claude const claude = getModel("anthropic", "claude-sonnet-4-20250514"); const context: Context = { messages: [], }; context.messages.push({ role: "user", content: "What is 25 * 18?" }); const claudeResponse = await complete(claude, context, { thinkingEnabled: true, }); context.messages.push(claudeResponse); // Switch to GPT-5 - it will see Claude's thinking as tagged text const gpt5 = getModel("openai", "gpt-5-mini"); context.messages.push({ role: "user", content: "Is that calculation correct?" }); const gptResponse = await complete(gpt5, context); context.messages.push(gptResponse); // Switch to Gemini const gemini = getModel("google", "gemini-2.5-flash"); context.messages.push({ role: "user", content: "What was the original question?" }); const geminiResponse = await complete(gemini, context); ``` -------------------------------- ### stdio Transport MCP Server Configuration Source: https://github.com/can1357/oh-my-pi/blob/main/docs/mcp-config.md Example configuration for an MCP server using the 'stdio' transport, which is the default. This setup uses 'npx' to run a local server with specified arguments. ```json { "$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json", "mcpServers": { "filesystem": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "/Users/alice/projects", "/Users/alice/Documents" ] } } } ``` -------------------------------- ### Install Oh My Pi via Linux/macOS Installer Script Source: https://github.com/can1357/oh-my-pi/blob/main/README.md Installs Oh My Pi using a curl command to download and execute an installation script. Supports source or binary installation, and specifying a Git reference. ```bash curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh ``` ```bash curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -s -- --source ``` ```bash curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -s -- --binary --ref v3.20.1 ``` ```bash curl -fsSL https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.sh | sh -s -- --source --ref main ``` -------------------------------- ### Minimal Agent Session Setup Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/sdk/README.md Demonstrates the simplest way to create an agent session using default settings. ```typescript import { AuthStorage, createAgentSession, discoverAuthStorage, discoverModels, discoverSkills, discoverHooks, discoverCustomTools, discoverContextFiles, discoverSlashCommands, loadSettings, buildSystemPrompt, ModelRegistry, SessionManager, BUILTIN_TOOLS, HIDDEN_TOOLS, createTools, ResolveTool, } from "@oh-my-pi/pi-coding-agent"; // Auth and models setup const authStorage = discoverAuthStorage(); const modelRegistry = discoverModels(authStorage); // Minimal const { session } = await createAgentSession({ authStorage, modelRegistry }); ``` -------------------------------- ### Agent Initialization Source: https://github.com/can1357/oh-my-pi/blob/main/packages/agent/README.md Demonstrates how to instantiate the Agent class with various configuration options. ```APIDOC ## Agent Options ```typescript const agent = new Agent({ // Initial state initialState: { systemPrompt: string[], model: Model, thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh", tools: AgentTool[], messages: AgentMessage[], }, // Convert AgentMessage[] to LLM Message[] (required for custom message types) convertToLlm: (messages) => messages.filter(...), // Transform context before convertToLlm (for pruning, compaction) transformContext: async (messages, signal) => pruneOldMessages(messages), // How to handle queued messages: "one-at-a-time" (default) or "all" queueMode: "one-at-a-time", // Custom stream function (for proxy backends) streamFn: streamProxy, // Dynamic API key resolution (for expiring OAuth tokens) getApiKey: async (provider) => refreshToken(), // Tool execution context (late-bound UI/session access) getToolContext: () => ({ /* app-defined */ }), }); ``` ``` -------------------------------- ### RPC Client with Startup Flags Source: https://github.com/can1357/oh-my-pi/blob/main/python/omp-rpc/README.md Shows how to configure the RpcClient with various startup flags like thinking level, session toggles, and tools. This avoids manual construction of extra arguments. ```python from omp_rpc import RpcClient with RpcClient( model="openrouter/anthropic/claude-sonnet-4.6", thinking="high", no_session=True, no_skills=True, no_rules=True, tools=("read", "edit", "write"), append_system_prompt="Focus on reproducible benchmark behavior.", ) as client: print(client.get_state().thinking_level) ``` -------------------------------- ### Install Oh My Pi via Windows PowerShell Script Source: https://github.com/can1357/oh-my-pi/blob/main/README.md Installs Oh My Pi using a PowerShell command to download and execute an installation script. Supports binary or source installation, and specifying a Git reference. ```powershell irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1 | iex ``` ```powershell & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Binary -Ref v3.20.1 ``` ```powershell & ([scriptblock]::Create((irm https://raw.githubusercontent.com/can1357/oh-my-pi/main/scripts/install.ps1))) -Source -Ref main ``` -------------------------------- ### Full Patch Example Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/prompts/tools/apply-patch.md Demonstrates a complete patch file including adding, updating (with rename), and deleting files. Ensure all operations are clearly defined with appropriate headers. ```shell *** Begin Patch *** Add File: hello.txt +Hello world *** Update File: src/app.py *** Move to: src/main.py @@ def greet(): -print("Hi") +print("Hello, world!") *** Delete File: obsolete.txt *** End Patch ``` -------------------------------- ### Correct Environment Variable and Path Handling Source: https://github.com/can1357/oh-my-pi/blob/main/docs/porting-from-pi-mono.md This example demonstrates the correct way to handle environment variables and construct paths using Node.js standard library modules, which are compatible with Bun. ```typescript import * as os from "node:os"; import * as fs from "node:fs"; import * as path from "node:path"; const configDir = path.join(os.homedir(), ".config", "myapp"); const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "myapp-")); ``` -------------------------------- ### Quick Start with @oh-my-pi/pi-agent Source: https://github.com/can1357/oh-my-pi/blob/main/packages/agent/README.md Initialize an agent, subscribe to events for streaming output, and send an initial prompt. ```typescript import { Agent } from "@oh-my-pi/pi-agent"; import { getModel } from "@oh-my-pi/pi-ai"; const agent = new Agent({ initialState: { systemPrompt: ["You are a helpful assistant."], model: getModel("anthropic", "claude-sonnet-4-20250514"), }, }); agent.subscribe((event) => { if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") { // Stream just the new text chunk process.stdout.write(event.assistantMessageEvent.delta); } }); await agent.prompt("Hello!"); ``` -------------------------------- ### Delete File Example Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/src/prompts/tools/patch.md Example of deleting the file 'obsolete.txt'. No diff content is required for deletion. ```bash edit {"path":"obsolete.txt","edits":[{"op":"delete"}]} ``` -------------------------------- ### Basic RPC Client Usage Source: https://github.com/can1357/oh-my-pi/blob/main/python/omp-rpc/README.md Demonstrates basic usage of the RpcClient to get state and prompt the assistant. Ensure the RpcClient is initialized with a provider and model. ```python from omp_rpc import RpcClient with RpcClient(provider="anthropic", model="claude-sonnet-4-5") as client: state = client.get_state() print(state.model.id if state.model else "no model") turn = client.prompt_and_wait("Reply with just the word hello") print(turn.require_assistant_text()) ``` -------------------------------- ### TypeScript Extension Example for pi-coding-agent Source: https://github.com/can1357/oh-my-pi/blob/main/packages/coding-agent/examples/extensions/README.md A detailed TypeScript example showcasing how to write custom extensions for the pi-coding-agent. It covers subscribing to lifecycle events like 'tool_call', registering custom tools with parameters, and registering simple commands. This example requires the '@oh-my-pi/pi-coding-agent' and '@sinclair/typebox' dependencies. ```typescript import type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent"; import { Type } from "@sinclair/typebox"; export default function (pi: ExtensionAPI) { // Subscribe to lifecycle events 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 custom tools pi.registerTool({ name: "greet", label: "Greeting", description: "Generate a greeting", parameters: Type.Object({ name: Type.String({ description: "Name to greet" }), }), async execute(toolCallId, params, onUpdate, ctx, signal) { return { content: [{ type: "text", text: `Hello, ${params.name}!` }], details: {}, }; }, }); // Register commands pi.registerCommand("hello", { description: "Say hello", handler: async (args, ctx) => { ctx.ui.notify("Hello!", "info"); }, }); } ``` -------------------------------- ### Create and Manage Agent Sessions Source: https://context7.com/can1357/oh-my-pi/llms.txt Demonstrates creating agent sessions with different session managers (in-memory and file-backed). Shows how to resume or reopen existing sessions. ```typescript import { createAgentSession, SessionManager } from "@oh-my-pi/pi-coding-agent"; // In-memory: no filesystem I/O const { session: ephemeral } = await createAgentSession({ sessionManager: SessionManager.inMemory(), }); console.log(ephemeral.sessionFile); // undefined // File-backed: persists to ~/.omp/agent/sessions/----/_.jsonl const { session: persistent } = await createAgentSession({ sessionManager: SessionManager.create(process.cwd()), }); console.log(persistent.sessionFile); // "/home/user/.omp/agent/sessions/.../xyz.jsonl" // Continue the most recent session for this cwd (or create new if none) const { session: resumed } = await createAgentSession({ sessionManager: await SessionManager.continueRecent(process.cwd()), }); // List sessions for a project, open a specific one const sessions = await SessionManager.list(process.cwd()); // sessions[0] → { id, path, title, firstMessage, timestamp } if (sessions.length > 0) { const { session: reopened } = await createAgentSession({ sessionManager: await SessionManager.open(sessions[0].path), }); console.log(`Reopened session: ${reopened.sessionId}`); } ```