refactor: finish companion rename migration

Complete the remaining pi-to-companion rename across companion-os, web, vm-orchestrator, docker, and archived fixtures.

Verification:
- semantic rg sweeps for Pi/piConfig/getPi/.pi runtime references
- npm run check in apps/companion-os (fails in this worktree: biome not found)

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Harivansh Rathi 2026-03-10 07:39:32 -05:00
parent e8fe3d54af
commit 536241053c
303 changed files with 3603 additions and 3602 deletions

View file

@ -1,20 +1,20 @@
# Compaction & Branch Summarization
LLMs have limited context windows. When conversations grow too long, pi uses compaction to summarize older content while preserving recent work. This page covers both auto-compaction and branch summarization.
LLMs have limited context windows. When conversations grow too long, companion uses compaction to summarize older content while preserving recent work. This page covers both auto-compaction and branch summarization.
**Source files** ([pi-mono](https://github.com/badlogic/pi-mono)):
**Source files** ([companion-mono](https://github.com/badlogic/companion-mono)):
- [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) - Auto-compaction logic
- [`packages/coding-agent/src/core/compaction/branch-summarization.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) - Branch summarization
- [`packages/coding-agent/src/core/compaction/utils.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/utils.ts) - Shared utilities (file tracking, serialization)
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Entry types (`CompactionEntry`, `BranchSummaryEntry`)
- [`packages/coding-agent/src/core/extensions/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/extensions/types.ts) - Extension event types
- [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) - Auto-compaction logic
- [`packages/coding-agent/src/core/compaction/branch-summarization.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) - Branch summarization
- [`packages/coding-agent/src/core/compaction/utils.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/utils.ts) - Shared utilities (file tracking, serialization)
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Entry types (`CompactionEntry`, `BranchSummaryEntry`)
- [`packages/coding-agent/src/core/extensions/types.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/extensions/types.ts) - Extension event types
For TypeScript definitions in your project, inspect `node_modules/@mariozechner/pi-coding-agent/dist/`.
For TypeScript definitions in your project, inspect `node_modules/@mariozechner/companion-coding-agent/dist/`.
## Overview
Pi has two summarization mechanisms:
Companion has two summarization mechanisms:
| Mechanism | Trigger | Purpose |
| -------------------- | ---------------------------------------- | ----------------------------------------- |
@ -33,13 +33,13 @@ Auto-compaction triggers when:
contextTokens > contextWindow - reserveTokens
```
By default, `reserveTokens` is 16384 tokens (configurable in `~/.pi/agent/settings.json` or `<project-dir>/.pi/settings.json`). This leaves room for the LLM's response.
By default, `reserveTokens` is 16384 tokens (configurable in `~/.companion/agent/settings.json` or `<project-dir>/.companion/settings.json`). This leaves room for the LLM's response.
You can also trigger manually with `/compact [instructions]`, where optional instructions focus the summary.
### How It Works
1. **Find cut point**: Walk backwards from newest message, accumulating token estimates until `keepRecentTokens` (default 20k, configurable in `~/.pi/agent/settings.json` or `<project-dir>/.pi/settings.json`) is reached
1. **Find cut point**: Walk backwards from newest message, accumulating token estimates until `keepRecentTokens` (default 20k, configurable in `~/.companion/agent/settings.json` or `<project-dir>/.companion/settings.json`) is reached
2. **Extract messages**: Collect messages from previous compaction (or start) up to cut point
3. **Generate summary**: Call LLM to summarize with structured format
4. **Append entry**: Save `CompactionEntry` with summary and `firstKeptEntryId`
@ -101,7 +101,7 @@ Split turn (one huge turn exceeds budget):
turnPrefixMessages = [usr, ass, tool, ass, tool, tool]
```
For split turns, pi generates two summaries and merges them:
For split turns, companion generates two summaries and merges them:
1. **History summary**: Previous context (if any)
2. **Turn prefix summary**: The early part of the split turn
@ -119,7 +119,7 @@ Never cut at tool results (they must stay with their tool call).
### CompactionEntry Structure
Defined in [`session-manager.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts):
Defined in [`session-manager.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/session-manager.ts):
```typescript
interface CompactionEntry<T = unknown> {
@ -143,13 +143,13 @@ interface CompactionDetails {
Extensions can store any JSON-serializable data in `details`. The default compaction tracks file operations, but custom extension implementations can use their own structure.
See [`prepareCompaction()`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) and [`compact()`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) for the implementation.
See [`prepareCompaction()`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) and [`compact()`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) for the implementation.
## Branch Summarization
### When It Triggers
When you use `/tree` to navigate to a different branch, pi offers to summarize the work you're leaving. This injects context from the left branch into the new branch.
When you use `/tree` to navigate to a different branch, companion offers to summarize the work you're leaving. This injects context from the left branch into the new branch.
### How It Works
@ -178,7 +178,7 @@ After navigation with summary:
### Cumulative File Tracking
Both compaction and branch summarization track files cumulatively. When generating a summary, pi extracts file operations from:
Both compaction and branch summarization track files cumulatively. When generating a summary, companion extracts file operations from:
- Tool calls in the messages being summarized
- Previous compaction or branch summary `details` (if any)
@ -187,7 +187,7 @@ This means file tracking accumulates across multiple compactions or nested branc
### BranchSummaryEntry Structure
Defined in [`session-manager.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts):
Defined in [`session-manager.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/session-manager.ts):
```typescript
interface BranchSummaryEntry<T = unknown> {
@ -210,7 +210,7 @@ interface BranchSummaryDetails {
Same as compaction, extensions can store custom data in `details`.
See [`collectEntriesForBranchSummary()`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), [`prepareBranchEntries()`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), and [`generateBranchSummary()`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) for the implementation.
See [`collectEntriesForBranchSummary()`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), [`prepareBranchEntries()`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), and [`generateBranchSummary()`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) for the implementation.
## Summary Format
@ -263,7 +263,7 @@ path/to/changed.ts
### Message Serialization
Before summarization, messages are serialized to text via [`serializeConversation()`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/compaction/utils.ts):
Before summarization, messages are serialized to text via [`serializeConversation()`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/compaction/utils.ts):
```
[User]: What they said
@ -277,14 +277,14 @@ This prevents the model from treating it as a conversation to continue.
## Custom Summarization via Extensions
Extensions can intercept and customize both compaction and branch summarization. See [`extensions/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/extensions/types.ts) for event type definitions.
Extensions can intercept and customize both compaction and branch summarization. See [`extensions/types.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/extensions/types.ts) for event type definitions.
### session_before_compact
Fired before auto-compaction or `/compact`. Can cancel or provide custom summary. See `SessionBeforeCompactEvent` and `CompactionPreparation` in the types file.
```typescript
pi.on("session_before_compact", async (event, ctx) => {
companion.on("session_before_compact", async (event, ctx) => {
const { preparation, branchEntries, customInstructions, signal } = event;
// preparation.messagesToSummarize - messages to summarize
@ -323,9 +323,9 @@ To generate a summary with your own model, convert messages to text using `seria
import {
convertToLlm,
serializeConversation,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
pi.on("session_before_compact", async (event, ctx) => {
companion.on("session_before_compact", async (event, ctx) => {
const { preparation } = event;
// Convert AgentMessage[] to Message[], then serialize to text
@ -359,7 +359,7 @@ See [custom-compaction.ts](../examples/extensions/custom-compaction.ts) for a co
Fired before `/tree` navigation. Always fires regardless of whether user chose to summarize. Can cancel navigation or provide custom summary.
```typescript
pi.on("session_before_tree", async (event, ctx) => {
companion.on("session_before_tree", async (event, ctx) => {
const { preparation, signal } = event;
// preparation.targetId - where we're navigating to
@ -389,7 +389,7 @@ See `SessionBeforeTreeEvent` and `TreePreparation` in the types file.
## Settings
Configure compaction in `~/.pi/agent/settings.json` or `<project-dir>/.pi/settings.json`:
Configure compaction in `~/.companion/agent/settings.json` or `<project-dir>/.companion/settings.json`:
```json
{

View file

@ -1,6 +1,6 @@
# Custom Providers
Extensions can register custom model providers via `pi.registerProvider()`. This enables:
Extensions can register custom model providers via `companion.registerProvider()`. This enables:
- **Proxies** - Route requests through corporate proxies or API gateways
- **Custom endpoints** - Use self-hosted or private model deployments
@ -22,16 +22,16 @@ Extensions can register custom model providers via `pi.registerProvider()`. This
## Quick Reference
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@mariozechner/companion-coding-agent";
export default function (pi: ExtensionAPI) {
export default function (companion: ExtensionAPI) {
// Override baseUrl for existing provider
pi.registerProvider("anthropic", {
companion.registerProvider("anthropic", {
baseUrl: "https://proxy.example.com",
});
// Register new provider with models
pi.registerProvider("my-provider", {
companion.registerProvider("my-provider", {
baseUrl: "https://api.example.com",
apiKey: "MY_API_KEY",
api: "openai-completions",
@ -56,19 +56,19 @@ The simplest use case: redirect an existing provider through a proxy.
```typescript
// All Anthropic requests now go through your proxy
pi.registerProvider("anthropic", {
companion.registerProvider("anthropic", {
baseUrl: "https://proxy.example.com",
});
// Add custom headers to OpenAI requests
pi.registerProvider("openai", {
companion.registerProvider("openai", {
headers: {
"X-Custom-Header": "value",
},
});
// Both baseUrl and headers
pi.registerProvider("google", {
companion.registerProvider("google", {
baseUrl: "https://ai-gateway.corp.com/google",
headers: {
"X-Corp-Auth": "CORP_AUTH_TOKEN", // env var or literal
@ -83,7 +83,7 @@ When only `baseUrl` and/or `headers` are provided (no `models`), all existing mo
To add a completely new provider, specify `models` along with the required configuration.
```typescript
pi.registerProvider("my-llm", {
companion.registerProvider("my-llm", {
baseUrl: "https://api.my-llm.com/v1",
apiKey: "MY_LLM_API_KEY", // env var name or literal value
api: "openai-completions", // which streaming API to use
@ -110,11 +110,11 @@ When `models` is provided, it **replaces** all existing models for that provider
## Unregister Provider
Use `pi.unregisterProvider(name)` to remove a provider that was previously registered via `pi.registerProvider(name, ...)`:
Use `companion.unregisterProvider(name)` to remove a provider that was previously registered via `companion.registerProvider(name, ...)`:
```typescript
// Register
pi.registerProvider("my-llm", {
companion.registerProvider("my-llm", {
baseUrl: "https://api.my-llm.com/v1",
apiKey: "MY_LLM_API_KEY",
api: "openai-completions",
@ -132,7 +132,7 @@ pi.registerProvider("my-llm", {
});
// Later, remove it
pi.unregisterProvider("my-llm");
companion.unregisterProvider("my-llm");
```
Unregistering removes that provider's dynamic models, API key fallback, OAuth provider registration, and custom stream handler registrations. Any built-in models or provider behavior that were overridden are restored.
@ -167,7 +167,7 @@ models: [
supportsDeveloperRole: false, // use "system" instead of "developer"
supportsReasoningEffort: true,
reasoningEffortMap: {
// map pi-ai levels to provider values
// map companion-ai levels to provider values
minimal: "default",
low: "default",
medium: "default",
@ -191,7 +191,7 @@ models: [
If your provider expects `Authorization: Bearer <key>` but doesn't use a standard API, set `authHeader: true`:
```typescript
pi.registerProvider("custom-api", {
companion.registerProvider("custom-api", {
baseUrl: "https://api.example.com",
apiKey: "MY_API_KEY",
authHeader: true, // adds Authorization: Bearer header
@ -205,9 +205,9 @@ pi.registerProvider("custom-api", {
Add OAuth/SSO authentication that integrates with `/login`:
```typescript
import type { OAuthCredentials, OAuthLoginCallbacks } from "@mariozechner/pi-ai";
import type { OAuthCredentials, OAuthLoginCallbacks } from "@mariozechner/companion-ai";
pi.registerProvider("corporate-ai", {
companion.registerProvider("corporate-ai", {
baseUrl: "https://ai.corp.com/v1",
api: "openai-responses",
models: [...],
@ -283,7 +283,7 @@ interface OAuthLoginCallbacks {
### OAuthCredentials
Credentials are persisted in `~/.pi/agent/auth.json`:
Credentials are persisted in `~/.companion/agent/auth.json`:
```typescript
interface OAuthCredentials {
@ -299,12 +299,12 @@ For providers with non-standard APIs, implement `streamSimple`. Study the existi
**Reference implementations:**
- [anthropic.ts](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
- [mistral.ts](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/mistral.ts) - Mistral Conversations API
- [openai-completions.ts](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
- [openai-responses.ts](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
- [google.ts](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
- [amazon-bedrock.ts](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
- [anthropic.ts](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
- [mistral.ts](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/providers/mistral.ts) - Mistral Conversations API
- [openai-completions.ts](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
- [openai-responses.ts](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
- [google.ts](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
- [amazon-bedrock.ts](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
### Stream Pattern
@ -319,7 +319,7 @@ import {
type SimpleStreamOptions,
calculateCost,
createAssistantMessageEventStream,
} from "@mariozechner/pi-ai";
} from "@mariozechner/companion-ai";
function streamMyProvider(
model: Model<any>,
@ -487,7 +487,7 @@ calculateCost(model, output.usage);
Register your stream function:
```typescript
pi.registerProvider("my-provider", {
companion.registerProvider("my-provider", {
baseUrl: "https://api.example.com",
apiKey: "MY_API_KEY",
api: "my-custom-api",
@ -498,7 +498,7 @@ pi.registerProvider("my-provider", {
## Testing Your Implementation
Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/badlogic/pi-mono/tree/main/packages/ai/test):
Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/badlogic/companion-mono/tree/main/packages/ai/test):
| Test | Purpose |
| ---------------------------------- | --------------------------------- |

View file

@ -5,8 +5,8 @@ See [AGENTS.md](../../../AGENTS.md) for additional guidelines.
## Setup
```bash
git clone https://github.com/badlogic/pi-mono
cd pi-mono
git clone https://github.com/badlogic/companion-mono
cd companion-mono
npm install
npm run build
```
@ -14,7 +14,7 @@ npm run build
Run from source:
```bash
./pi-test.sh
./companion-test.sh
```
## Forking / Rebranding
@ -23,9 +23,9 @@ Configure via `package.json`:
```json
{
"piConfig": {
"name": "pi",
"configDir": ".pi"
"companionConfig": {
"name": "companion",
"configDir": ".companion"
}
}
```
@ -46,7 +46,7 @@ Never use `__dirname` directly for package assets.
## Debug Command
`/debug` (hidden) writes to `~/.pi/agent/pi-debug.log`:
`/debug` (hidden) writes to `~/.companion/agent/companion-debug.log`:
- Rendered TUI lines with ANSI codes
- Last messages sent to the LLM

File diff suppressed because it is too large Load diff

View file

@ -1,14 +1,14 @@
# JSON Event Stream Mode
```bash
pi --mode json "Your prompt"
companion --mode json "Your prompt"
```
Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs.
Outputs all session events as JSON lines to stdout. Useful for integrating companion into other tools or custom UIs.
## Event Types
Events are defined in [`AgentSessionEvent`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
Events are defined in [`AgentSessionEvent`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
```typescript
type AgentSessionEvent =
@ -36,7 +36,7 @@ type AgentSessionEvent =
};
```
Base events from [`AgentEvent`](https://github.com/badlogic/pi-mono/blob/main/packages/agent/src/types.ts#L179):
Base events from [`AgentEvent`](https://github.com/badlogic/companion-mono/blob/main/packages/agent/src/types.ts#L179):
```typescript
type AgentEvent =
@ -83,13 +83,13 @@ type AgentEvent =
## Message Types
Base messages from [`packages/ai/src/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/types.ts#L134):
Base messages from [`packages/ai/src/types.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/types.ts#L134):
- `UserMessage` (line 134)
- `AssistantMessage` (line 140)
- `ToolResultMessage` (line 152)
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
- `BashExecutionMessage` (line 29)
- `CustomMessage` (line 46)
@ -125,5 +125,5 @@ Followed by events as they occur:
## Example
```bash
pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
companion --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
```

View file

@ -1,6 +1,6 @@
# Keybindings
All keyboard shortcuts can be customized via `~/.pi/agent/keybindings.json`. Each action can be bound to one or more keys.
All keyboard shortcuts can be customized via `~/.companion/agent/keybindings.json`. Each action can be bound to one or more keys.
## Key Format
@ -132,7 +132,7 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, etc.
## Custom Configuration
Create `~/.pi/agent/keybindings.json`:
Create `~/.companion/agent/keybindings.json`:
```json
{

View file

@ -1,6 +1,6 @@
# Custom Models
Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.pi/agent/models.json`.
Add custom providers and models (Ollama, vLLM, LM Studio, proxies) via `~/.companion/agent/models.json`.
## Table of Contents

View file

@ -1,14 +1,14 @@
> pi can help you create pi packages. Ask it to bundle your extensions, skills, prompt templates, or themes.
> companion can help you create companion packages. Ask it to bundle your extensions, skills, prompt templates, or themes.
# Pi Packages
# Companion Packages
Pi packages bundle extensions, skills, prompt templates, and themes so you can share them through npm or git. A package can declare resources in `package.json` under the `pi` key, or use conventional directories.
Companion packages bundle extensions, skills, prompt templates, and themes so you can share them through npm or git. A package can declare resources in `package.json` under the `companion` key, or use conventional directories.
## Table of Contents
- [Install and Manage](#install-and-manage)
- [Package Sources](#package-sources)
- [Creating a Pi Package](#creating-a-pi-package)
- [Creating a Companion Package](#creating-a-companion-package)
- [Package Structure](#package-structure)
- [Dependencies](#dependencies)
- [Package Filtering](#package-filtering)
@ -17,32 +17,32 @@ Pi packages bundle extensions, skills, prompt templates, and themes so you can s
## Install and Manage
> **Security:** Pi packages run with full system access. Extensions execute arbitrary code, and skills can instruct the model to perform any action including running executables. Review source code before installing third-party packages.
> **Security:** Companion packages run with full system access. Extensions execute arbitrary code, and skills can instruct the model to perform any action including running executables. Review source code before installing third-party packages.
```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
companion install npm:@foo/bar@1.0.0
companion install git:github.com/user/repo@v1
companion install https://github.com/user/repo # raw URLs work too
companion install /absolute/path/to/package
companion install ./relative/path/to/package
pi remove npm:@foo/bar
pi list # show installed packages from settings
pi update # update all non-pinned packages
companion remove npm:@foo/bar
companion list # show installed packages from settings
companion update # update all non-pinned packages
```
By default, `install` and `remove` write to global settings (`~/.pi/agent/settings.json`). Use `-l` to write to project settings (`.pi/settings.json`) instead. Project settings can be shared with your team, and pi installs any missing packages automatically on startup.
By default, `install` and `remove` write to global settings (`~/.companion/agent/settings.json`). Use `-l` to write to project settings (`.companion/settings.json`) instead. Project settings can be shared with your team, and companion installs any missing packages automatically on startup.
To try a package without installing it, use `--extension` or `-e`. This installs to a temporary directory for the current run only:
```bash
pi -e npm:@foo/bar
pi -e git:github.com/user/repo
companion -e npm:@foo/bar
companion -e git:github.com/user/repo
```
## Package Sources
Pi accepts three source types in settings and `pi install`.
Companion accepts three source types in settings and `companion install`.
### npm
@ -51,9 +51,9 @@ npm:@scope/pkg@1.2.3
npm:pkg
```
- Versioned specs are pinned and skipped by `pi update`.
- Versioned specs are pinned and skipped by `companion update`.
- Global installs use `npm install -g`.
- Project installs go under `.pi/npm/`.
- Project installs go under `.companion/npm/`.
### git
@ -69,21 +69,21 @@ ssh://git@github.com/user/repo@v1
- HTTPS and SSH URLs are both supported.
- SSH URLs use your configured SSH keys automatically (respects `~/.ssh/config`).
- For non-interactive runs (for example CI), you can set `GIT_TERMINAL_PROMPT=0` to disable credential prompts and set `GIT_SSH_COMMAND` (for example `ssh -o BatchMode=yes -o ConnectTimeout=5`) to fail fast.
- Refs pin the package and skip `pi update`.
- Cloned to `~/.pi/agent/git/<host>/<path>` (global) or `.pi/git/<host>/<path>` (project).
- Refs pin the package and skip `companion update`.
- Cloned to `~/.companion/agent/git/<host>/<path>` (global) or `.companion/git/<host>/<path>` (project).
- Runs `npm install` after clone or pull if `package.json` exists.
**SSH examples:**
```bash
# git@host:path shorthand (requires git: prefix)
pi install git:git@github.com:user/repo
companion install git:git@github.com:user/repo
# ssh:// protocol format
pi install ssh://git@github.com/user/repo
companion install ssh://git@github.com/user/repo
# With version ref
pi install git:git@github.com:user/repo@v1.0.0
companion install git:git@github.com:user/repo@v1.0.0
```
### Local Paths
@ -93,17 +93,17 @@ pi install git:git@github.com:user/repo@v1.0.0
./relative/path/to/package
```
Local paths point to files or directories on disk and are added to settings without copying. Relative paths are resolved against the settings file they appear in. If the path is a file, it loads as a single extension. If it is a directory, pi loads resources using package rules.
Local paths point to files or directories on disk and are added to settings without copying. Relative paths are resolved against the settings file they appear in. If the path is a file, it loads as a single extension. If it is a directory, companion loads resources using package rules.
## Creating a Pi Package
## Creating a Companion Package
Add a `pi` manifest to `package.json` or use conventional directories. Include the `pi-package` keyword for discoverability.
Add a `companion` manifest to `package.json` or use conventional directories. Include the `companion-package` keyword for discoverability.
```json
{
"name": "my-package",
"keywords": ["pi-package"],
"pi": {
"keywords": ["companion-package"],
"companion": {
"extensions": ["./extensions"],
"skills": ["./skills"],
"prompts": ["./prompts"],
@ -116,13 +116,13 @@ Paths are relative to the package root. Arrays support glob patterns and `!exclu
### Gallery Metadata
The [package gallery](https://shittycodingagent.ai/packages) displays packages tagged with `pi-package`. Add `video` or `image` fields to show a preview:
The [package gallery](https://shittycodingagent.ai/packages) displays packages tagged with `companion-package`. Add `video` or `image` fields to show a preview:
```json
{
"name": "my-package",
"keywords": ["pi-package"],
"pi": {
"keywords": ["companion-package"],
"companion": {
"extensions": ["./extensions"],
"video": "https://example.com/demo.mp4",
"image": "https://example.com/screenshot.png"
@ -139,7 +139,7 @@ If both are set, video takes precedence.
### Convention Directories
If no `pi` manifest is present, pi auto-discovers resources from these directories:
If no `companion` manifest is present, companion auto-discovers resources from these directories:
- `extensions/` loads `.ts` and `.js` files
- `skills/` recursively finds `SKILL.md` folders and loads top-level `.md` files as skills
@ -148,11 +148,11 @@ If no `pi` manifest is present, pi auto-discovers resources from these directori
## Dependencies
Third party runtime dependencies belong in `dependencies` in `package.json`. Dependencies that do not register extensions, skills, prompt templates, or themes also belong in `dependencies`. When pi installs a package from npm or git, it runs `npm install`, so those dependencies are installed automatically.
Third party runtime dependencies belong in `dependencies` in `package.json`. Dependencies that do not register extensions, skills, prompt templates, or themes also belong in `dependencies`. When companion installs a package from npm or git, it runs `npm install`, so those dependencies are installed automatically.
Pi bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@mariozechner/pi-ai`, `@mariozechner/pi-agent-core`, `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `@sinclair/typebox`.
Companion bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@mariozechner/companion-ai`, `@mariozechner/companion-agent-core`, `@mariozechner/companion-coding-agent`, `@mariozechner/companion-tui`, `@sinclair/typebox`.
Other pi packages must be bundled in your tarball. Add them to `dependencies` and `bundledDependencies`, then reference their resources through `node_modules/` paths. Pi loads packages with separate module roots, so separate installs do not collide or share modules.
Other companion packages must be bundled in your tarball. Add them to `dependencies` and `bundledDependencies`, then reference their resources through `node_modules/` paths. Companion loads packages with separate module roots, so separate installs do not collide or share modules.
Example:
@ -162,7 +162,7 @@ Example:
"shitty-extensions": "^1.0.1"
},
"bundledDependencies": ["shitty-extensions"],
"pi": {
"companion": {
"extensions": ["extensions", "node_modules/shitty-extensions/extensions"],
"skills": ["skills", "node_modules/shitty-extensions/skills"]
}
@ -199,7 +199,7 @@ Filter what a package loads using the object form in settings:
## Enable and Disable Resources
Use `pi config` to enable or disable extensions, skills, prompt templates, and themes from installed packages and local directories. Works for both global (`~/.pi/agent`) and project (`.pi/`) scopes.
Use `companion config` to enable or disable extensions, skills, prompt templates, and themes from installed packages and local directories. Works for both global (`~/.companion/agent`) and project (`.companion/`) scopes.
## Scope and Deduplication

View file

@ -1,4 +1,4 @@
> pi can create prompt templates. Ask it to build one for your workflow.
> companion can create prompt templates. Ask it to build one for your workflow.
# Prompt Templates
@ -6,11 +6,11 @@ Prompt templates are Markdown snippets that expand into full prompts. Type `/nam
## Locations
Pi loads prompt templates from:
Companion loads prompt templates from:
- Global: `~/.pi/agent/prompts/*.md`
- Project: `.pi/prompts/*.md`
- Packages: `prompts/` directories or `pi.prompts` entries in `package.json`
- Global: `~/.companion/agent/prompts/*.md`
- Project: `.companion/prompts/*.md`
- Packages: `prompts/` directories or `companion.prompts` entries in `package.json`
- Settings: `prompts` array with files or directories
- CLI: `--prompt-template <path>` (repeatable)

View file

@ -1,6 +1,6 @@
# Providers
Pi supports subscription-based providers via OAuth and API key providers via environment variables or auth file. For each provider, pi knows all available models. The list is updated with every pi release.
Companion supports subscription-based providers via OAuth and API key providers via environment variables or auth file. For each provider, companion knows all available models. The list is updated with every companion release.
## Table of Contents
@ -21,7 +21,7 @@ Use `/login` in interactive mode, then select a provider:
- Google Gemini CLI
- Google Antigravity
Use `/logout` to clear credentials. Tokens are stored in `~/.pi/agent/auth.json` and auto-refresh when expired.
Use `/logout` to clear credentials. Tokens are stored in `~/.companion/agent/auth.json` and auto-refresh when expired.
### GitHub Copilot
@ -48,7 +48,7 @@ Set via environment variable:
```bash
export ANTHROPIC_API_KEY=sk-ant-...
pi
companion
```
| Provider | Environment Variable | `auth.json` key |
@ -71,11 +71,11 @@ pi
| MiniMax | `MINIMAX_API_KEY` | `minimax` |
| MiniMax (China) | `MINIMAX_CN_API_KEY` | `minimax-cn` |
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/env-api-keys.ts).
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/env-api-keys.ts).
#### Auth File
Store credentials in `~/.pi/agent/auth.json`:
Store credentials in `~/.companion/agent/auth.json`:
```json
{
@ -144,7 +144,7 @@ export AWS_REGION=us-west-2
Also supports ECS task roles (`AWS_CONTAINER_CREDENTIALS_*`) and IRSA (`AWS_WEB_IDENTITY_TOKEN_FILE`).
```bash
pi --provider amazon-bedrock --model us.anthropic.claude-sonnet-4-20250514-v1:0
companion --provider amazon-bedrock --model us.anthropic.claude-sonnet-4-20250514-v1:0
```
If you are connecting to a Bedrock API proxy, the following environment variables can be used:

View file

@ -2,12 +2,12 @@
RPC mode enables headless operation of the coding agent via a JSON protocol over stdin/stdout. This is useful for embedding the agent in other applications, IDEs, or custom UIs.
**Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@mariozechner/pi-coding-agent` instead of spawning a subprocess. See [`src/core/agent-session.ts`](../src/core/agent-session.ts) for the API. For a subprocess-based TypeScript client, see [`src/modes/rpc/rpc-client.ts`](../src/modes/rpc/rpc-client.ts).
**Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@mariozechner/companion-coding-agent` instead of spawning a subprocess. See [`src/core/agent-session.ts`](../src/core/agent-session.ts) for the API. For a subprocess-based TypeScript client, see [`src/modes/rpc/rpc-client.ts`](../src/modes/rpc/rpc-client.ts).
## Starting RPC Mode
```bash
pi --mode rpc [options]
companion --mode rpc [options]
```
Common options:
@ -60,7 +60,7 @@ With images:
If the agent is streaming and no `streamingBehavior` is specified, the command returns an error.
**Extension commands**: If the message is an extension command (e.g., `/mycommand`), it executes immediately even during streaming. Extension commands manage their own LLM interaction via `pi.sendMessage()`.
**Extension commands**: If the message is an extension command (e.g., `/mycommand`), it executes immediately even during streaming. Extension commands manage their own LLM interaction via `companion.sendMessage()`.
**Input expansion**: Skill commands (`/skill:name`) and prompt templates (`/template`) are expanded before sending/queueing.
@ -503,7 +503,7 @@ If output was truncated, includes `fullOutputPath`:
"exitCode": 0,
"cancelled": false,
"truncated": true,
"fullOutputPath": "/tmp/pi-bash-abc123.log"
"fullOutputPath": "/tmp/companion-bash-abc123.log"
}
}
```
@ -752,21 +752,21 @@ Response:
"name": "session-name",
"description": "Set or clear session name",
"source": "extension",
"path": "/home/user/.pi/agent/extensions/session.ts"
"path": "/home/user/.companion/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"
"path": "/home/user/myproject/.companion/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"
"path": "/home/user/.companion/agent/skills/brave-search/SKILL.md"
}
]
}
@ -778,12 +778,12 @@ Each command has:
- `name`: Command name (invoke with `/name`)
- `description`: Human-readable description (optional for extension commands)
- `source`: What kind of command:
- `"extension"`: Registered via `pi.registerCommand()` in an extension
- `"extension"`: Registered via `companion.registerCommand()` in an extension
- `"prompt"`: Loaded from a prompt template `.md` file
- `"skill"`: Loaded from a skill directory (name is prefixed with `skill:`)
- `location`: Where it was loaded from (optional, not present for extensions):
- `"user"`: User-level (`~/.pi/agent/`)
- `"project"`: Project-level (`./.pi/agent/`)
- `"user"`: User-level (`~/.companion/agent/`)
- `"project"`: Project-level (`./.companion/agent/`)
- `"path"`: Explicit path via CLI or settings
- `path`: Absolute file path to the command source (optional)
@ -1173,7 +1173,7 @@ Set the terminal window/tab title. Fire-and-forget.
"type": "extension_ui_request",
"id": "uuid-8",
"method": "setTitle",
"title": "pi - my project"
"title": "companion - my project"
}
```
@ -1372,7 +1372,7 @@ import subprocess
import json
proc = subprocess.Popen(
["pi", "--mode", "rpc", "--no-session"],
["companion", "--mode", "rpc", "--no-session"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True
@ -1411,7 +1411,7 @@ For a complete example of handling the extension UI protocol, see [`examples/rpc
const { spawn } = require("child_process");
const readline = require("readline");
const agent = spawn("pi", ["--mode", "rpc", "--no-session"]);
const agent = spawn("companion", ["--mode", "rpc", "--no-session"]);
readline.createInterface({ input: agent.stdout }).on("line", (line) => {
const event = JSON.parse(line);

View file

@ -1,8 +1,8 @@
> pi can help you use the SDK. Ask it to build an integration for your use case.
> companion can help you use the SDK. Ask it to build an integration for your use case.
# SDK
The SDK provides programmatic access to pi's agent capabilities. Use it to embed pi in other applications, build custom interfaces, or integrate with automated workflows.
The SDK provides programmatic access to companion's agent capabilities. Use it to embed companion in other applications, build custom interfaces, or integrate with automated workflows.
**Example use cases:**
@ -22,7 +22,7 @@ import {
createAgentSession,
ModelRegistry,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
// Set up credential storage and model registry
const authStorage = AuthStorage.create();
@ -49,7 +49,7 @@ await session.prompt("What files are in the current directory?");
## Installation
```bash
npm install @mariozechner/pi-coding-agent
npm install @mariozechner/companion-coding-agent
```
The SDK is included in the main package. No separate installation needed.
@ -63,7 +63,7 @@ The main factory function. Creates an `AgentSession` with configurable options.
`createAgentSession()` uses a `ResourceLoader` to supply extensions, skills, prompt templates, themes, and context files. If you do not provide one, it uses `DefaultResourceLoader` with standard discovery.
```typescript
import { createAgentSession } from "@mariozechner/pi-coding-agent";
import { createAgentSession } from "@mariozechner/companion-coding-agent";
// Minimal: defaults with DefaultResourceLoader
const { session } = await createAgentSession();
@ -170,7 +170,7 @@ await session.prompt("After you're done, also check X", {
**Behavior:**
- **Extension commands** (e.g., `/mycommand`): Execute immediately, even during streaming. They manage their own LLM interaction via `pi.sendMessage()`.
- **Extension commands** (e.g., `/mycommand`): Execute immediately, even during streaming. They manage their own LLM interaction via `companion.sendMessage()`.
- **File-based prompt templates** (from `.md` files): Expanded to their content before sending/queueing.
- **During streaming without `streamingBehavior`**: Throws an error. Use `steer()` or `followUp()` directly, or specify the option.
@ -188,7 +188,7 @@ Both `steer()` and `followUp()` expand file-based prompt templates but error on
### Agent and AgentState
The `Agent` class (from `@mariozechner/pi-agent-core`) handles the core LLM interaction. Access it via `session.agent`.
The `Agent` class (from `@mariozechner/companion-agent-core`) handles the core LLM interaction. Access it via `session.agent`.
```typescript
// Access current state
@ -279,17 +279,17 @@ const { session } = await createAgentSession({
cwd: process.cwd(), // default
// Global config directory
agentDir: "~/.pi/agent", // default (expands ~)
agentDir: "~/.companion/agent", // default (expands ~)
});
```
`cwd` is used by `DefaultResourceLoader` for:
- Project extensions (`.pi/extensions/`)
- Project extensions (`.companion/extensions/`)
- Project skills:
- `.pi/skills/`
- `.companion/skills/`
- `.agents/skills/` in `cwd` and ancestor directories (up to git repo root, or filesystem root when not in a repo)
- Project prompts (`.pi/prompts/`)
- Project prompts (`.companion/prompts/`)
- Context files (`AGENTS.md` walking up from cwd)
- Session directory naming
@ -297,7 +297,7 @@ const { session } = await createAgentSession({
- Global extensions (`extensions/`)
- Global skills:
- `skills/` under `agentDir` (for example `~/.pi/agent/skills/`)
- `skills/` under `agentDir` (for example `~/.companion/agent/skills/`)
- `~/.agents/skills/`
- Global prompts (`prompts/`)
- Global context file (`AGENTS.md`)
@ -311,8 +311,8 @@ When you pass a custom `ResourceLoader`, `cwd` and `agentDir` no longer control
### Model
```typescript
import { getModel } from "@mariozechner/pi-ai";
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
import { getModel } from "@mariozechner/companion-ai";
import { AuthStorage, ModelRegistry } from "@mariozechner/companion-coding-agent";
const authStorage = AuthStorage.create();
const modelRegistry = new ModelRegistry(authStorage);
@ -359,9 +359,9 @@ API key resolution priority (handled by AuthStorage):
4. Fallback resolver (for custom provider keys from `models.json`)
```typescript
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
import { AuthStorage, ModelRegistry } from "@mariozechner/companion-coding-agent";
// Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
// Default: uses ~/.companion/agent/auth.json and ~/.companion/agent/models.json
const authStorage = AuthStorage.create();
const modelRegistry = new ModelRegistry(authStorage);
@ -396,7 +396,7 @@ Use a `ResourceLoader` to override the system prompt:
import {
createAgentSession,
DefaultResourceLoader,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const loader = new DefaultResourceLoader({
systemPromptOverride: () => "You are a helpful assistant.",
@ -419,7 +419,7 @@ import {
grepTool,
findTool,
lsTool,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
// Use built-in tool set
const { session } = await createAgentSession({
@ -447,7 +447,7 @@ import {
createGrepTool,
createFindTool,
createLsTool,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const cwd = "/path/to/project";
@ -466,7 +466,7 @@ const { session } = await createAgentSession({
**When you don't need factories:**
- If you omit `tools`, pi automatically creates them with the correct `cwd`
- If you omit `tools`, companion automatically creates them with the correct `cwd`
- If you use `process.cwd()` as your `cwd`, the pre-built instances work fine
**When you must use factories:**
@ -480,7 +480,7 @@ import { Type } from "@sinclair/typebox";
import {
createAgentSession,
type ToolDefinition,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
// Inline custom tool
const myTool: ToolDefinition = {
@ -502,23 +502,23 @@ const { session } = await createAgentSession({
});
```
Custom tools passed via `customTools` are combined with extension-registered tools. Extensions loaded by the ResourceLoader can also register tools via `pi.registerTool()`.
Custom tools passed via `customTools` are combined with extension-registered tools. Extensions loaded by the ResourceLoader can also register tools via `companion.registerTool()`.
### Extensions
Extensions are loaded by the `ResourceLoader`. `DefaultResourceLoader` discovers extensions from `~/.pi/agent/extensions/`, `.pi/extensions/`, and settings.json extension sources.
Extensions are loaded by the `ResourceLoader`. `DefaultResourceLoader` discovers extensions from `~/.companion/agent/extensions/`, `.companion/extensions/`, and settings.json extension sources.
```typescript
import {
createAgentSession,
DefaultResourceLoader,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const loader = new DefaultResourceLoader({
additionalExtensionPaths: ["/path/to/my-extension.ts"],
extensionFactories: [
(pi) => {
pi.on("agent_start", () => {
(companion) => {
companion.on("agent_start", () => {
console.log("[Inline Extension] Agent starting");
});
},
@ -531,13 +531,13 @@ const { session } = await createAgentSession({ resourceLoader: loader });
Extensions can register tools, subscribe to events, add commands, and more. See [extensions.md](extensions.md) for the full API.
**Event Bus:** Extensions can communicate via `pi.events`. Pass a shared `eventBus` to `DefaultResourceLoader` if you need to emit or listen from outside:
**Event Bus:** Extensions can communicate via `companion.events`. Pass a shared `eventBus` to `DefaultResourceLoader` if you need to emit or listen from outside:
```typescript
import {
createEventBus,
DefaultResourceLoader,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const eventBus = createEventBus();
const loader = new DefaultResourceLoader({
@ -555,7 +555,7 @@ import {
createAgentSession,
DefaultResourceLoader,
type Skill,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const customSkill: Skill = {
name: "my-skill",
@ -582,7 +582,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
import {
createAgentSession,
DefaultResourceLoader,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const loader = new DefaultResourceLoader({
agentsFilesOverride: (current) => ({
@ -604,7 +604,7 @@ import {
createAgentSession,
DefaultResourceLoader,
type PromptTemplate,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const customCommand: PromptTemplate = {
name: "deploy",
@ -632,7 +632,7 @@ Sessions use a tree structure with `id`/`parentId` linking, enabling in-place br
import {
createAgentSession,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
// In-memory (no persistence)
const { session } = await createAgentSession({
@ -707,7 +707,7 @@ import {
createAgentSession,
SettingsManager,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
// Default: loads from files (global + project merged)
const { session } = await createAgentSession({
@ -743,8 +743,8 @@ const { session } = await createAgentSession({
Settings load from two locations and merge:
1. Global: `~/.pi/agent/settings.json`
2. Project: `<cwd>/.pi/settings.json`
1. Global: `~/.companion/agent/settings.json`
2. Project: `<cwd>/.companion/settings.json`
Project overrides global. Nested objects merge keys. Setters modify global settings by default.
@ -763,7 +763,7 @@ Use `DefaultResourceLoader` to discover extensions, skills, prompts, themes, and
import {
DefaultResourceLoader,
getAgentDir,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const loader = new DefaultResourceLoader({
cwd,
@ -804,7 +804,7 @@ interface LoadExtensionsResult {
## Complete Example
```typescript
import { getModel } from "@mariozechner/pi-ai";
import { getModel } from "@mariozechner/companion-ai";
import { Type } from "@sinclair/typebox";
import {
AuthStorage,
@ -816,7 +816,7 @@ import {
readTool,
bashTool,
type ToolDefinition,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
// Set up auth storage (custom location)
const authStorage = AuthStorage.create("/custom/agent/auth.json");
@ -899,7 +899,7 @@ Full TUI interactive mode with editor, chat history, and all built-in commands:
import {
createAgentSession,
InteractiveMode,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const { session } = await createAgentSession({
/* ... */
@ -925,7 +925,7 @@ Single-shot mode: send prompts, output result, exit:
import {
createAgentSession,
runPrintMode,
} from "@mariozechner/pi-coding-agent";
} from "@mariozechner/companion-coding-agent";
const { session } = await createAgentSession({
/* ... */
@ -944,7 +944,7 @@ await runPrintMode(session, {
JSON-RPC mode for subprocess integration:
```typescript
import { createAgentSession, runRpcMode } from "@mariozechner/pi-coding-agent";
import { createAgentSession, runRpcMode } from "@mariozechner/companion-coding-agent";
const { session } = await createAgentSession({
/* ... */
@ -960,7 +960,7 @@ See [RPC documentation](rpc.md) for the JSON protocol.
For subprocess-based integration without building with the SDK, use the CLI directly:
```bash
pi --mode rpc --no-session
companion --mode rpc --no-session
```
See [RPC documentation](rpc.md) for the JSON protocol.

View file

@ -5,16 +5,16 @@ Sessions are stored as JSONL (JSON Lines) files. Each line is a JSON object with
## File Location
```
~/.pi/agent/sessions/--<path>--/<timestamp>_<uuid>.jsonl
~/.companion/agent/sessions/--<path>--/<timestamp>_<uuid>.jsonl
```
Where `<path>` is the working directory with `/` replaced by `-`.
## Deleting Sessions
Sessions can be removed by deleting their `.jsonl` files under `~/.pi/agent/sessions/`.
Sessions can be removed by deleting their `.jsonl` files under `~/.companion/agent/sessions/`.
Pi also supports deleting sessions interactively from `/resume` (select a session and press `Ctrl+D`, then confirm). When available, pi uses the `trash` CLI to avoid permanent deletion.
Companion also supports deleting sessions interactively from `/resume` (select a session and press `Ctrl+D`, then confirm). When available, companion uses the `trash` CLI to avoid permanent deletion.
## Session Version
@ -28,14 +28,14 @@ Existing sessions are automatically migrated to the current version (v3) when lo
## Source Files
Source on GitHub ([pi-mono](https://github.com/badlogic/pi-mono)):
Source on GitHub ([companion-mono](https://github.com/badlogic/companion-mono)):
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
- [`packages/ai/src/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
- [`packages/agent/src/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
- [`packages/ai/src/types.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
- [`packages/agent/src/types.ts`](https://github.com/badlogic/companion-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
For TypeScript definitions in your project, inspect `node_modules/@mariozechner/pi-coding-agent/dist/` and `node_modules/@mariozechner/pi-ai/dist/`.
For TypeScript definitions in your project, inspect `node_modules/@mariozechner/companion-coding-agent/dist/` and `node_modules/@mariozechner/companion-ai/dist/`.
## Message Types
@ -70,7 +70,7 @@ interface ToolCall {
}
```
### Base Message Types (from pi-ai)
### Base Message Types (from companion-ai)
```typescript
interface UserMessage {
@ -117,7 +117,7 @@ interface Usage {
}
```
### Extended Message Types (from pi-coding-agent)
### Extended Message Types (from companion-coding-agent)
```typescript
interface BashExecutionMessage {
@ -269,7 +269,7 @@ Created when context is compacted. Stores a summary of earlier messages.
Optional fields:
- `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if companion-generated (legacy field name)
### BranchSummaryEntry
@ -289,7 +289,7 @@ Created when switching branches via `/tree` with an LLM generated summary of the
Optional fields:
- `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if companion-generated (legacy field name)
### CustomEntry
@ -349,7 +349,7 @@ Set `label` to `undefined` to clear a label.
### SessionInfoEntry
Session metadata (e.g., user-defined display name). Set via `/name` command or `pi.setSessionName()` in extensions.
Session metadata (e.g., user-defined display name). Set via `/name` command or `companion.setSessionName()` in extensions.
```json
{

View file

@ -1,11 +1,11 @@
# Settings
Pi uses JSON settings files with project settings overriding global settings.
Companion uses JSON settings files with project settings overriding global settings.
| Location | Scope |
| --------------------------- | --------------------------- |
| `~/.pi/agent/settings.json` | Global (all projects) |
| `.pi/settings.json` | Project (current directory) |
| `~/.companion/agent/settings.json` | Global (all projects) |
| `.companion/settings.json` | Project (current directory) |
Edit directly or use `/settings` for common options.
@ -140,7 +140,7 @@ When a provider requests a retry delay longer than `maxDelayMs` (e.g., Google's
These settings define where to load extensions, skills, prompts, and themes from.
Paths in `~/.pi/agent/settings.json` resolve relative to `~/.pi/agent`. Paths in `.pi/settings.json` resolve relative to `.pi`. Absolute paths and `~` are supported.
Paths in `~/.companion/agent/settings.json` resolve relative to `~/.companion/agent`. Paths in `.companion/settings.json` resolve relative to `.companion`. Absolute paths and `~` are supported.
| Setting | Type | Default | Description |
| --------------------- | -------- | ------- | ------------------------------------------ |
@ -159,7 +159,7 @@ String form loads all resources from a package:
```json
{
"packages": ["pi-skills", "@org/my-extension"]
"packages": ["companion-skills", "@org/my-extension"]
}
```
@ -169,7 +169,7 @@ Object form filters which resources to load:
{
"packages": [
{
"source": "pi-skills",
"source": "companion-skills",
"skills": ["brave-search", "transcribe"],
"extensions": []
}
@ -197,22 +197,22 @@ See [packages.md](packages.md) for package management details.
"maxRetries": 3
},
"enabledModels": ["claude-*", "gpt-4o"],
"packages": ["pi-skills"]
"packages": ["companion-skills"]
}
```
## Project Overrides
Project settings (`.pi/settings.json`) override global settings. Nested objects are merged:
Project settings (`.companion/settings.json`) override global settings. Nested objects are merged:
```json
// ~/.pi/agent/settings.json (global)
// ~/.companion/agent/settings.json (global)
{
"theme": "dark",
"compaction": { "enabled": true, "reserveTokens": 16384 }
}
// .pi/settings.json (project)
// .companion/settings.json (project)
{
"compaction": { "reserveTokens": 8192 }
}

View file

@ -1,8 +1,8 @@
# Shell Aliases
Pi runs bash in non-interactive mode (`bash -c`), which doesn't expand aliases by default.
Companion runs bash in non-interactive mode (`bash -c`), which doesn't expand aliases by default.
To enable your shell aliases, add to `~/.pi/agent/settings.json`:
To enable your shell aliases, add to `~/.companion/agent/settings.json`:
```json
{

View file

@ -1,10 +1,10 @@
> pi can create skills. Ask it to build one for your use case.
> companion can create skills. Ask it to build one for your use case.
# Skills
Skills are self-contained capability packages that the agent loads on-demand. A skill provides specialized workflows, setup instructions, helper scripts, and reference documentation for specific tasks.
Pi implements the [Agent Skills standard](https://agentskills.io/specification), warning about violations but remaining lenient.
Companion implements the [Agent Skills standard](https://agentskills.io/specification), warning about violations but remaining lenient.
## Table of Contents
@ -21,15 +21,15 @@ Pi implements the [Agent Skills standard](https://agentskills.io/specification),
> **Security:** Skills can instruct the model to perform any action and may include executable code the model invokes. Review skill content before use.
Pi loads skills from:
Companion loads skills from:
- Global:
- `~/.pi/agent/skills/`
- `~/.companion/agent/skills/`
- `~/.agents/skills/`
- Project:
- `.pi/skills/`
- `.companion/skills/`
- `.agents/skills/` in `cwd` and ancestor directories (up to git repo root, or filesystem root when not in a repo)
- Packages: `skills/` directories or `pi.skills` entries in `package.json`
- Packages: `skills/` directories or `companion.skills` entries in `package.json`
- Settings: `skills` array with files or directories
- CLI: `--skill <path>` (repeatable, additive even with `--no-skills`)
@ -50,7 +50,7 @@ To use skills from Claude Code or OpenAI Codex, add their directories to setting
}
```
For project-level Claude Code skills, add to `.pi/settings.json`:
For project-level Claude Code skills, add to `.companion/settings.json`:
```json
{
@ -60,7 +60,7 @@ For project-level Claude Code skills, add to `.pi/settings.json`:
## How Skills Work
1. At startup, pi scans skill locations and extracts names and descriptions
1. At startup, companion scans skill locations and extracts names and descriptions
2. The system prompt includes available skills in XML format per the [specification](https://agentskills.io/integrate-skills)
3. When a task matches, the agent uses `read` to load the full SKILL.md (models don't always do this; use prompting or `/skill:name` to force it)
4. The agent follows the instructions, using relative paths to reference scripts and assets
@ -174,7 +174,7 @@ description: Helps with PDFs.
## Validation
Pi validates skills against the Agent Skills standard. Most issues produce warnings but still load the skill:
Companion validates skills against the Agent Skills standard. Most issues produce warnings but still load the skill:
- Name doesn't match parent directory
- Name exceeds 64 characters or contains invalid characters
@ -229,4 +229,4 @@ cd /path/to/brave-search && npm install
## Skill Repositories
- [Anthropic Skills](https://github.com/anthropics/skills) - Document processing (docx, pdf, pptx, xlsx), web development
- [Pi Skills](https://github.com/badlogic/pi-skills) - Web search, browser automation, Google APIs, transcription
- [Companion Skills](https://github.com/badlogic/companion-skills) - Web search, browser automation, Google APIs, transcription

View file

@ -1,6 +1,6 @@
# Terminal Setup
Pi uses the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/) for reliable modifier key detection. Most modern terminals support this protocol, but some require configuration.
Companion uses the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/) for reliable modifier key detection. Most modern terminals support this protocol, but some require configuration.
## Kitty, iTerm2
@ -66,6 +66,6 @@ If you already have an `actions` array, add the object to it.
The built-in terminal has limited escape sequence support. Shift+Enter cannot be distinguished from Enter in IntelliJ's terminal.
If you want the hardware cursor visible, set `PI_HARDWARE_CURSOR=1` before running pi (disabled by default for compatibility).
If you want the hardware cursor visible, set `COMPANION_HARDWARE_CURSOR=1` before running companion (disabled by default for compatibility).
Consider using a dedicated terminal emulator for the best experience.

View file

@ -1,6 +1,6 @@
# Termux (Android) Setup
Pi runs on Android via [Termux](https://termux.dev/), a terminal emulator and Linux environment for Android.
Companion runs on Android via [Termux](https://termux.dev/), a terminal emulator and Linux environment for Android.
## Prerequisites
@ -16,14 +16,14 @@ pkg update && pkg upgrade
# Install dependencies
pkg install nodejs termux-api git
# Install pi
npm install -g @mariozechner/pi-coding-agent
# Install companion
npm install -g @mariozechner/companion-coding-agent
# Create config directory
mkdir -p ~/.pi/agent
mkdir -p ~/.companion/agent
# Run pi
pi
# Run companion
companion
```
## Clipboard Support
@ -34,7 +34,7 @@ Image clipboard is not supported on Termux (the `ctrl+v` image paste feature wil
## Example AGENTS.md for Termux
Create `~/.pi/agent/AGENTS.md` to help the agent understand the Termux environment:
Create `~/.companion/agent/AGENTS.md` to help the agent understand the Termux environment:
````markdown
# Agent Environment: Termux on Android

View file

@ -1,4 +1,4 @@
> pi can create themes. Ask it to build one for your setup.
> companion can create themes. Ask it to build one for your setup.
# Themes
@ -16,12 +16,12 @@ Themes are JSON files that define colors for the TUI.
## Locations
Pi loads themes from:
Companion loads themes from:
- Built-in: `dark`, `light`
- Global: `~/.pi/agent/themes/*.json`
- Project: `.pi/themes/*.json`
- Packages: `themes/` directories or `pi.themes` entries in `package.json`
- Global: `~/.companion/agent/themes/*.json`
- Project: `.companion/themes/*.json`
- Packages: `themes/` directories or `companion.themes` entries in `package.json`
- Settings: `themes` array with files or directories
- CLI: `--theme <path>` (repeatable)
@ -37,22 +37,22 @@ Select a theme via `/settings` or in `settings.json`:
}
```
On first run, pi detects your terminal background and defaults to `dark` or `light`.
On first run, companion detects your terminal background and defaults to `dark` or `light`.
## Creating a Custom Theme
1. Create a theme file:
```bash
mkdir -p ~/.pi/agent/themes
vim ~/.pi/agent/themes/my-theme.json
mkdir -p ~/.companion/agent/themes
vim ~/.companion/agent/themes/my-theme.json
```
2. Define the theme with all required colors (see [Color Tokens](#color-tokens)):
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"$schema": "https://raw.githubusercontent.com/badlogic/companion-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"primary": "#00aaff",
@ -116,13 +116,13 @@ vim ~/.pi/agent/themes/my-theme.json
3. Select the theme via `/settings`.
**Hot reload:** When you edit the currently active custom theme file, pi reloads it automatically for immediate visual feedback.
**Hot reload:** When you edit the currently active custom theme file, companion reloads it automatically for immediate visual feedback.
## Theme Format
```json
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"$schema": "https://raw.githubusercontent.com/badlogic/companion-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"blue": "#0066cc",
@ -268,7 +268,7 @@ Four formats are supported:
### Terminal Compatibility
Pi uses 24-bit RGB colors. Most modern terminals support this (iTerm2, Kitty, WezTerm, Windows Terminal, VS Code). For older terminals with only 256-color support, pi falls back to the nearest approximation.
Companion uses 24-bit RGB colors. Most modern terminals support this (iTerm2, Kitty, WezTerm, Windows Terminal, VS Code). For older terminals with only 256-color support, companion falls back to the nearest approximation.
Check truecolor support:

View file

@ -209,8 +209,8 @@ interface SessionTreeEvent {
### Example: Custom Summarizer
```typescript
export default function (pi: HookAPI) {
pi.on("session_before_tree", async (event, ctx) => {
export default function (companion: HookAPI) {
companion.on("session_before_tree", async (event, ctx) => {
if (!event.preparation.userWantsSummary) return;
if (event.preparation.entriesToSummarize.length === 0) return;

View file

@ -1,10 +1,10 @@
> pi can create TUI components. Ask it to build one for your use case.
> companion can create TUI components. Ask it to build one for your use case.
# TUI Components
Extensions and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
**Source:** [`@mariozechner/pi-tui`](https://github.com/badlogic/pi-mono/tree/main/packages/tui)
**Source:** [`@mariozechner/companion-tui`](https://github.com/badlogic/companion-mono/tree/main/packages/tui)
## Component Interface
@ -37,7 +37,7 @@ import {
CURSOR_MARKER,
type Component,
type Focusable,
} from "@mariozechner/pi-tui";
} from "@mariozechner/companion-tui";
class MyInput implements Component, Focusable {
focused: boolean = false; // Set by TUI when focus changes
@ -66,7 +66,7 @@ This enables IME candidate windows to appear at the correct position for CJK inp
When a container component (dialog, selector, etc.) contains an `Input` or `Editor` child, the container must implement `Focusable` and propagate the focus state to the child. Otherwise, the hardware cursor won't be positioned correctly for IME input.
```typescript
import { Container, type Focusable, Input } from "@mariozechner/pi-tui";
import { Container, type Focusable, Input } from "@mariozechner/companion-tui";
class SearchDialog extends Container implements Focusable {
private searchInput: Input;
@ -96,18 +96,18 @@ Without this propagation, typing with an IME (Chinese, Japanese, Korean, etc.) w
**In extensions** via `ctx.ui.custom()`:
```typescript
pi.on("session_start", async (_event, ctx) => {
companion.on("session_start", async (_event, ctx) => {
const handle = ctx.ui.custom(myComponent);
// handle.requestRender() - trigger re-render
// handle.close() - restore normal UI
});
```
**In custom tools** via `pi.ui.custom()`:
**In custom tools** via `companion.ui.custom()`:
```typescript
async execute(toolCallId, params, onUpdate, ctx, signal) {
const handle = pi.ui.custom(myComponent);
const handle = companion.ui.custom(myComponent);
// ...
handle.close();
}
@ -191,10 +191,10 @@ See [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for compre
## Built-in Components
Import from `@mariozechner/pi-tui`:
Import from `@mariozechner/companion-tui`:
```typescript
import { Text, Box, Container, Spacer, Markdown } from "@mariozechner/pi-tui";
import { Text, Box, Container, Spacer, Markdown } from "@mariozechner/companion-tui";
```
### Text
@ -276,7 +276,7 @@ const image = new Image(
Use `matchesKey()` for key detection:
```typescript
import { matchesKey, Key } from "@mariozechner/pi-tui";
import { matchesKey, Key } from "@mariozechner/companion-tui";
handleInput(data: string) {
if (matchesKey(data, Key.up)) {
@ -303,7 +303,7 @@ handleInput(data: string) {
**Critical:** Each line from `render()` must not exceed the `width` parameter.
```typescript
import { visibleWidth, truncateToWidth } from "@mariozechner/pi-tui";
import { visibleWidth, truncateToWidth } from "@mariozechner/companion-tui";
render(width: number): string[] {
// Truncate long lines
@ -327,7 +327,7 @@ import {
Key,
truncateToWidth,
visibleWidth,
} from "@mariozechner/pi-tui";
} from "@mariozechner/companion-tui";
class MySelector {
private items: string[];
@ -382,7 +382,7 @@ class MySelector {
Usage in an extension:
```typescript
pi.registerCommand("pick", {
companion.registerCommand("pick", {
description: "Pick an item",
handler: async (args, ctx) => {
const items = ["Option A", "Option B", "Option C"];
@ -444,8 +444,8 @@ renderResult(result, options, theme) {
**For Markdown**, use `getMarkdownTheme()`:
```typescript
import { getMarkdownTheme } from "@mariozechner/pi-coding-agent";
import { Markdown } from "@mariozechner/pi-tui";
import { getMarkdownTheme } from "@mariozechner/companion-coding-agent";
import { Markdown } from "@mariozechner/companion-tui";
renderResult(result, options, theme) {
const mdTheme = getMarkdownTheme();
@ -464,10 +464,10 @@ interface MyTheme {
## Debug logging
Set `PI_TUI_WRITE_LOG` to capture the raw ANSI stream written to stdout.
Set `COMPANION_TUI_WRITE_LOG` to capture the raw ANSI stream written to stdout.
```bash
PI_TUI_WRITE_LOG=/tmp/tui-ansi.log npx tsx packages/tui/test/chat-simple.ts
COMPANION_TUI_WRITE_LOG=/tmp/tui-ansi.log npx tsx packages/tui/test/chat-simple.ts
```
## Performance
@ -606,19 +606,19 @@ These patterns cover the most common UI needs in extensions. **Copy these patter
### Pattern 1: Selection Dialog (SelectList)
For letting users pick from a list of options. Use `SelectList` from `@mariozechner/pi-tui` with `DynamicBorder` for framing.
For letting users pick from a list of options. Use `SelectList` from `@mariozechner/companion-tui` with `DynamicBorder` for framing.
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { DynamicBorder } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@mariozechner/companion-coding-agent";
import { DynamicBorder } from "@mariozechner/companion-coding-agent";
import {
Container,
type SelectItem,
SelectList,
Text,
} from "@mariozechner/pi-tui";
} from "@mariozechner/companion-tui";
pi.registerCommand("pick", {
companion.registerCommand("pick", {
handler: async (_args, ctx) => {
const items: SelectItem[] = [
{ value: "opt1", label: "Option 1", description: "First option" },
@ -691,9 +691,9 @@ pi.registerCommand("pick", {
For operations that take time and should be cancellable. `BorderedLoader` shows a spinner and handles escape to cancel.
```typescript
import { BorderedLoader } from "@mariozechner/pi-coding-agent";
import { BorderedLoader } from "@mariozechner/companion-coding-agent";
pi.registerCommand("fetch", {
companion.registerCommand("fetch", {
handler: async (_args, ctx) => {
const result = await ctx.ui.custom<string | null>(
(tui, theme, _kb, done) => {
@ -722,18 +722,18 @@ pi.registerCommand("fetch", {
### Pattern 3: Settings/Toggles (SettingsList)
For toggling multiple settings. Use `SettingsList` from `@mariozechner/pi-tui` with `getSettingsListTheme()`.
For toggling multiple settings. Use `SettingsList` from `@mariozechner/companion-tui` with `getSettingsListTheme()`.
```typescript
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
import { getSettingsListTheme } from "@mariozechner/companion-coding-agent";
import {
Container,
type SettingItem,
SettingsList,
Text,
} from "@mariozechner/pi-tui";
} from "@mariozechner/companion-tui";
pi.registerCommand("settings", {
companion.registerCommand("settings", {
handler: async (_args, ctx) => {
const items: SettingItem[] = [
{
@ -854,8 +854,8 @@ Token stats available via `ctx.sessionManager.getBranch()` and `ctx.model`.
Replace the main input editor with a custom implementation. Useful for modal editing (vim), different keybindings (emacs), or specialized input handling.
```typescript
import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { matchesKey, truncateToWidth } from "@mariozechner/pi-tui";
import { CustomEditor, type ExtensionAPI } from "@mariozechner/companion-coding-agent";
import { matchesKey, truncateToWidth } from "@mariozechner/companion-tui";
type Mode = "normal" | "insert";
@ -917,8 +917,8 @@ class VimEditor extends CustomEditor {
}
}
export default function (pi: ExtensionAPI) {
pi.on("session_start", (_event, ctx) => {
export default function (companion: ExtensionAPI) {
companion.on("session_start", (_event, ctx) => {
// Factory receives theme and keybindings from the app
ctx.ui.setEditorComponent(
(tui, theme, keybindings) => new VimEditor(theme, keybindings),

View file

@ -1,8 +1,8 @@
# Windows Setup
Pi requires a bash shell on Windows. Checked locations (in order):
Companion requires a bash shell on Windows. Checked locations (in order):
1. Custom path from `~/.pi/agent/settings.json`
1. Custom path from `~/.companion/agent/settings.json`
2. Git Bash (`C:\Program Files\Git\bin\bash.exe`)
3. `bash.exe` on PATH (Cygwin, MSYS2, WSL)