chore: migrate packages to earendil works scope

This commit is contained in:
Mario Zechner
2026-05-07 17:13:48 +02:00
325 changed files with 1319 additions and 3038 deletions

View File

@@ -2,6 +2,10 @@
## [Unreleased]
### Changed
- Updated repository links and package references for the move to `earendil-works/pi-mono` and `@earendil-works/*` package scopes.
## [0.73.1] - 2026-05-07
### New Features

View File

@@ -9,8 +9,8 @@
</p>
<p align="center">
<a href="https://discord.com/invite/3cU7Bz4UPx"><img alt="Discord" src="https://img.shields.io/badge/discord-community-5865F2?style=flat-square&logo=discord&logoColor=white" /></a>
<a href="https://www.npmjs.com/package/@mariozechner/pi-coding-agent"><img alt="npm" src="https://img.shields.io/npm/v/@mariozechner/pi-coding-agent?style=flat-square" /></a>
<a href="https://github.com/badlogic/pi-mono/actions/workflows/ci.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/badlogic/pi-mono/ci.yml?style=flat-square&branch=main" /></a>
<a href="https://www.npmjs.com/package/@earendil-works/pi-coding-agent"><img alt="npm" src="https://img.shields.io/npm/v/@earendil-works/pi-coding-agent?style=flat-square" /></a>
<a href="https://github.com/earendil-works/pi-mono/actions/workflows/ci.yml"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/earendil-works/pi-mono/ci.yml?style=flat-square&branch=main" /></a>
</p>
<p align="center">
<a href="https://pi.dev">pi.dev</a> domain graciously donated by
@@ -73,7 +73,7 @@ I regularly publish my own `pi-mono` work sessions here:
## Quick Start
```bash
npm install -g @mariozechner/pi-coding-agent
npm install -g @earendil-works/pi-coding-agent
```
Authenticate with an API key:
@@ -432,7 +432,7 @@ See [docs/packages.md](docs/packages.md).
### SDK
```typescript
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@mariozechner/pi-coding-agent";
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent";
const authStorage = AuthStorage.create();
const modelRegistry = ModelRegistry.create(authStorage);
@@ -646,6 +646,6 @@ MIT
## See Also
- [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit
- [@mariozechner/pi-agent-core](https://www.npmjs.com/package/@mariozechner/pi-agent-core): Agent framework
- [@mariozechner/pi-tui](https://www.npmjs.com/package/@mariozechner/pi-tui): Terminal UI components
- [@earendil-works/pi-ai](https://www.npmjs.com/package/@earendil-works/pi-ai): Core LLM toolkit
- [@earendil-works/pi-agent-core](https://www.npmjs.com/package/@earendil-works/pi-agent-core): Agent framework
- [@earendil-works/pi-tui](https://www.npmjs.com/package/@earendil-works/pi-tui): Terminal UI components

View File

@@ -2,14 +2,14 @@
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.
**Source files** ([pi-mono](https://github.com/badlogic/pi-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
**Source files** ([pi-mono](https://github.com/earendil-works/pi-mono)):
- [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/earendil-works/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/earendil-works/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/earendil-works/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/earendil-works/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/earendil-works/pi-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/@earendil-works/pi-coding-agent/dist/`.
## Overview
@@ -118,7 +118,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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts):
```typescript
interface CompactionEntry<T = unknown> {
@@ -142,7 +142,7 @@ 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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) and [`compact()`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) for the implementation.
## Branch Summarization
@@ -185,7 +185,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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts):
```typescript
interface BranchSummaryEntry<T = unknown> {
@@ -208,7 +208,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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), [`prepareBranchEntries()`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), and [`generateBranchSummary()`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) for the implementation.
## Summary Format
@@ -252,7 +252,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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/compaction/utils.ts):
```
[User]: What they said
@@ -268,7 +268,7 @@ Tool results are truncated to 2000 characters during serialization. Content beyo
## 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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/extensions/types.ts) for event type definitions.
### session_before_compact
@@ -309,7 +309,7 @@ pi.on("session_before_compact", async (event, ctx) => {
To generate a summary with your own model, convert messages to text using `serializeConversation`:
```typescript
import { convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
import { convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
pi.on("session_before_compact", async (event, ctx) => {
const { preparation } = event;

View File

@@ -30,7 +30,7 @@ See these complete provider examples:
## Quick Reference
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// Override baseUrl for existing provider
@@ -96,7 +96,7 @@ To add a completely new provider, specify `models` along with the required confi
If the model list comes from a remote endpoint, use an async extension factory:
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default async function (pi: ExtensionAPI) {
const response = await fetch("http://localhost:1234/v1/models");
@@ -252,7 +252,7 @@ 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 "@earendil-works/pi-ai";
pi.registerProvider("corporate-ai", {
baseUrl: "https://ai.corp.com/v1",
@@ -345,12 +345,12 @@ interface OAuthCredentials {
For providers with non-standard APIs, implement `streamSimple`. Study the existing provider implementations before writing your own:
**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/earendil-works/pi-mono/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
- [mistral.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/mistral.ts) - Mistral Conversations API
- [openai-completions.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
- [openai-responses.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
- [google.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
- [amazon-bedrock.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
### Stream Pattern
@@ -365,7 +365,7 @@ import {
type SimpleStreamOptions,
calculateCost,
createAssistantMessageEventStream,
} from "@mariozechner/pi-ai";
} from "@earendil-works/pi-ai";
function streamMyProvider(
model: Model<any>,
@@ -522,7 +522,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/earendil-works/pi-mono/tree/main/packages/ai/test):
| Test | Purpose |
|------|---------|

View File

@@ -5,7 +5,7 @@ See [AGENTS.md](../../../AGENTS.md) for additional guidelines.
## Setup
```bash
git clone https://github.com/badlogic/pi-mono
git clone https://github.com/earendil-works/pi-mono
cd pi-mono
npm install
npm run build

View File

@@ -57,7 +57,7 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
Create `~/.pi/agent/extensions/my-extension.ts`:
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
export default function (pi: ExtensionAPI) {
@@ -139,10 +139,10 @@ To share extensions via npm or git as pi packages, see [packages.md](packages.md
| Package | Purpose |
|---------|---------|
| `@mariozechner/pi-coding-agent` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
| `@earendil-works/pi-coding-agent` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
| `typebox` | Schema definitions for tool parameters |
| `@mariozechner/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
| `@mariozechner/pi-tui` | TUI components for custom rendering |
| `@earendil-works/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
| `@earendil-works/pi-tui` | TUI components for custom rendering |
npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), run `npm install`, and imports from `node_modules/` are resolved automatically.
@@ -155,7 +155,7 @@ Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
An extension exports a default factory function that receives `ExtensionAPI`. The factory can be synchronous or asynchronous:
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// Subscribe to events
@@ -184,7 +184,7 @@ If the factory returns a `Promise`, pi awaits it before continuing startup. That
Use an async factory for one-time startup work such as fetching remote configuration or dynamically discovering available models.
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default async function (pi: ExtensionAPI) {
const response = await fetch("http://localhost:1234/v1/models");
@@ -688,7 +688,7 @@ Behavior guarantees:
- Return values from `tool_call` only control blocking via `{ block: true, reason?: string }`
```typescript
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
pi.on("tool_call", async (event, ctx) => {
// event.toolName - "bash", "read", "write", "edit", etc.
@@ -724,7 +724,7 @@ export type MyToolInput = Static<typeof myToolSchema>;
Use `isToolCallEventType` with explicit type parameters:
```typescript
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
import { isToolCallEventType } from "@earendil-works/pi-coding-agent";
import type { MyToolInput } from "my-extension";
pi.on("tool_call", (event) => {
@@ -748,7 +748,7 @@ In parallel tool mode, `tool_result` and `tool_execution_end` may interleave in
Use `ctx.signal` for nested async work inside the handler. This lets Esc cancel model calls, `fetch()`, and other abort-aware operations started by the extension.
```typescript
import { isBashToolResult } from "@mariozechner/pi-coding-agent";
import { isBashToolResult } from "@earendil-works/pi-coding-agent";
pi.on("tool_result", async (event, ctx) => {
// event.toolName, event.toolCallId, event.input
@@ -776,7 +776,7 @@ pi.on("tool_result", async (event, ctx) => {
Fired when user executes `!` or `!!` commands. **Can intercept.**
```typescript
import { createLocalBashOperations } from "@mariozechner/pi-coding-agent";
import { createLocalBashOperations } from "@earendil-works/pi-coding-agent";
pi.on("user_bash", (event, ctx) => {
// event.command - the bash command
@@ -1087,7 +1087,7 @@ Options:
To discover available sessions, use the static `SessionManager.list()` or `SessionManager.listAll()` methods:
```typescript
import { SessionManager } from "@mariozechner/pi-coding-agent";
import { SessionManager } from "@earendil-works/pi-coding-agent";
pi.registerCommand("switch", {
description: "Switch to another session",
@@ -1181,7 +1181,7 @@ Tools run with `ExtensionContext`, so they cannot call `ctx.reload()` directly.
Example tool the LLM can call to trigger reload:
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
export default function (pi: ExtensionAPI) {
@@ -1230,7 +1230,7 @@ See [dynamic-tools.ts](../examples/extensions/dynamic-tools.ts) for a full examp
```typescript
import { Type } from "typebox";
import { StringEnum } from "@mariozechner/pi-ai";
import { StringEnum } from "@earendil-works/pi-ai";
pi.registerTool({
name: "my_tool",
@@ -1388,7 +1388,7 @@ pi.registerCommand("stats", {
Optional: add argument auto-completion for `/command ...`:
```typescript
import type { AutocompleteItem } from "@mariozechner/pi-tui";
import type { AutocompleteItem } from "@earendil-works/pi-tui";
pi.registerCommand("deploy", {
description: "Deploy to an environment",
@@ -1678,7 +1678,7 @@ Pass the real target file path to `withFileMutationQueue()`, not the raw user ar
Queue the entire mutation window on that target path. That includes read-modify-write logic, not just the final write.
```typescript
import { withFileMutationQueue } from "@mariozechner/pi-coding-agent";
import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
@@ -1703,8 +1703,8 @@ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
```typescript
import { Type } from "typebox";
import { StringEnum } from "@mariozechner/pi-ai";
import { Text } from "@mariozechner/pi-tui";
import { StringEnum } from "@earendil-works/pi-ai";
import { Text } from "@earendil-works/pi-tui";
pi.registerTool({
name: "my_tool",
@@ -1772,7 +1772,7 @@ async execute(toolCallId, params) {
}
```
**Important:** Use `StringEnum` from `@mariozechner/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
**Important:** Use `StringEnum` from `@earendil-works/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
**Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when pi resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
@@ -1845,20 +1845,20 @@ See [examples/extensions/tool-override.ts](../examples/extensions/tool-override.
**Your implementation must match the exact result shape**, including the `details` type. The UI and session logic depend on these shapes for rendering and state tracking.
Built-in tool implementations:
- [read.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
- [bash.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
- [edit.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/edit.ts)
- [write.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/write.ts)
- [grep.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
- [find.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
- [ls.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
- [read.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
- [bash.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
- [edit.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/edit.ts)
- [write.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/write.ts)
- [grep.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
- [find.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
- [ls.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
### Remote Execution
Built-in tools support pluggable operations for delegating to remote systems (SSH, containers, etc.):
```typescript
import { createReadTool, createBashTool, type ReadOperations } from "@mariozechner/pi-coding-agent";
import { createReadTool, createBashTool, type ReadOperations } from "@earendil-works/pi-coding-agent";
// Create tool with custom operations
const remoteRead = createReadTool(cwd, {
@@ -1889,7 +1889,7 @@ For `user_bash`, extensions can reuse pi's local shell backend via `createLocalB
The bash tool also supports a spawn hook to adjust the command, cwd, or env before execution:
```typescript
import { createBashTool } from "@mariozechner/pi-coding-agent";
import { createBashTool } from "@earendil-works/pi-coding-agent";
const bashTool = createBashTool(cwd, {
spawnHook: ({ command, cwd, env }) => ({
@@ -1919,7 +1919,7 @@ import {
formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
DEFAULT_MAX_BYTES, // 50KB
DEFAULT_MAX_LINES, // 2000
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
async execute(toolCallId, params, signal, onUpdate, ctx) {
const output = await runCommand();
@@ -1974,7 +1974,7 @@ export default function (pi: ExtensionAPI) {
### Custom Rendering
Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how tool rows are composed.
Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how tool rows are composed.
By default, tool output is wrapped in a `Box` that handles padding and background. A defined `renderCall` or `renderResult` must return a `Component`. If a slot renderer is not defined, `tool-execution.ts` uses fallback rendering for that slot.
@@ -2010,7 +2010,7 @@ Use `context.state` for cross-slot shared state. Keep slot-local caches on the r
Renders the tool call or header:
```typescript
import { Text } from "@mariozechner/pi-tui";
import { Text } from "@earendil-works/pi-tui";
renderCall(args, theme, context) {
const text = (context.lastComponent as Text | undefined) ?? new Text("", 0, 0);
@@ -2055,7 +2055,7 @@ If a slot intentionally has no visible content, return an empty `Component` such
Use `keyHint()` to display keybinding hints that respect the active keybinding configuration:
```typescript
import { keyHint } from "@mariozechner/pi-coding-agent";
import { keyHint } from "@earendil-works/pi-coding-agent";
renderResult(result, { expanded }, theme, context) {
let text = theme.fg("success", "✓ Done");
@@ -2329,7 +2329,7 @@ See [github-issue-autocomplete.ts](../examples/extensions/github-issue-autocompl
For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
```typescript
import { Text, Component } from "@mariozechner/pi-tui";
import { Text, Component } from "@earendil-works/pi-tui";
const result = await ctx.ui.custom<boolean>((tui, theme, keybindings, done) => {
const text = new Text("Press Enter to confirm, Escape to cancel", 1, 1);
@@ -2387,8 +2387,8 @@ See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts]
Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
```typescript
import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { matchesKey } from "@mariozechner/pi-tui";
import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { matchesKey } from "@earendil-works/pi-tui";
class VimEditor extends CustomEditor {
private mode: "normal" | "insert" = "insert";
@@ -2438,7 +2438,7 @@ See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
Register a custom renderer for messages with your `customType`:
```typescript
import { Text } from "@mariozechner/pi-tui";
import { Text } from "@earendil-works/pi-tui";
pi.registerMessageRenderer("my-extension", (message, options, theme) => {
const { expanded } = options;
@@ -2487,7 +2487,7 @@ theme.strikethrough(text)
For syntax highlighting in custom tool renderers:
```typescript
import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
import { highlightCode, getLanguageFromPath } from "@earendil-works/pi-coding-agent";
// Highlight code with explicit language
const highlighted = highlightCode("const x = 1;", "typescript", theme);

View File

@@ -7,7 +7,7 @@ Pi is a minimal terminal coding harness. It is designed to stay small at the cor
Install pi with npm:
```bash
npm install -g @mariozechner/pi-coding-agent
npm install -g @earendil-works/pi-coding-agent
```
Then run it in a project directory:

View File

@@ -8,7 +8,7 @@ Outputs all session events as JSON lines to stdout. Useful for integrating pi in
## 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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
```typescript
type AgentSessionEvent =
@@ -22,7 +22,7 @@ type AgentSessionEvent =
`queue_update` emits the full pending steering and follow-up queues whenever they change. `compaction_start` and `compaction_end` cover both manual and automatic compaction.
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/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts#L179):
```typescript
type AgentEvent =
@@ -44,12 +44,12 @@ 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/earendil-works/pi-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/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
- `BashExecutionMessage` (line 29)
- `CustomMessage` (line 46)
- `BranchSummaryMessage` (line 55)

View File

@@ -163,7 +163,7 @@ If no `pi` manifest is present, pi auto-discovers resources from these directori
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.
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`, `typebox`.
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: `@earendil-works/pi-ai`, `@earendil-works/pi-agent-core`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, `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.

View File

@@ -74,7 +74,7 @@ pi
| Xiaomi MiMo Token Plan (Amsterdam) | `XIAOMI_TOKEN_PLAN_AMS_API_KEY` | `xiaomi-token-plan-ams` |
| Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` | `xiaomi-token-plan-sgp` |
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/earendil-works/pi-mono/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/env-api-keys.ts).
#### Auth File

View File

@@ -7,7 +7,7 @@ This page gets you from install to a useful first pi session.
Pi is distributed as an npm package:
```bash
npm install -g @mariozechner/pi-coding-agent
npm install -g @earendil-works/pi-coding-agent
```
Then start pi in the project directory you want it to work on:

View File

@@ -2,7 +2,7 @@
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 `@earendil-works/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).
## Starting RPC Mode

View File

@@ -16,7 +16,7 @@ See [examples/sdk/](../examples/sdk/) for working examples from minimal to full
## Quick Start
```typescript
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@mariozechner/pi-coding-agent";
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent";
// Set up credential storage and model registry
const authStorage = AuthStorage.create();
@@ -40,7 +40,7 @@ await session.prompt("What files are in the current directory?");
## Installation
```bash
npm install @mariozechner/pi-coding-agent
npm install @earendil-works/pi-coding-agent
```
The SDK is included in the main package. No separate installation needed.
@@ -54,7 +54,7 @@ The main factory function for a single `AgentSession`.
`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 "@earendil-works/pi-coding-agent";
// Minimal: defaults with DefaultResourceLoader
const { session } = await createAgentSession();
@@ -132,7 +132,7 @@ import {
createAgentSessionServices,
getAgentDir,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
@@ -239,7 +239,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 `@earendil-works/pi-agent-core`) handles the core LLM interaction. Access it via `session.agent`.
```typescript
// Access current state
@@ -368,8 +368,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 "@earendil-works/pi-ai";
import { AuthStorage, ModelRegistry } from "@earendil-works/pi-coding-agent";
const authStorage = AuthStorage.create();
const modelRegistry = ModelRegistry.create(authStorage);
@@ -416,7 +416,7 @@ 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 "@earendil-works/pi-coding-agent";
// Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
const authStorage = AuthStorage.create();
@@ -452,7 +452,7 @@ const simpleRegistry = ModelRegistry.inMemory(authStorage);
Use a `ResourceLoader` to override the system prompt:
```typescript
import { createAgentSession, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
import { createAgentSession, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
systemPromptOverride: () => "You are a helpful assistant.",
@@ -472,7 +472,7 @@ import {
readOnlyTools, // read, grep, find, ls
readTool, bashTool, editTool, writeTool,
grepTool, findTool, lsTool,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
// Use built-in tool set
const { session } = await createAgentSession({
@@ -500,7 +500,7 @@ import {
createGrepTool,
createFindTool,
createLsTool,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const cwd = "/path/to/project";
@@ -530,7 +530,7 @@ const { session } = await createAgentSession({
```typescript
import { Type } from "typebox";
import { createAgentSession, defineTool } from "@mariozechner/pi-coding-agent";
import { createAgentSession, defineTool } from "@earendil-works/pi-coding-agent";
// Inline custom tool
const myTool = defineTool({
@@ -563,7 +563,7 @@ Custom tools passed via `customTools` are combined with extension-registered too
Extensions are loaded by the `ResourceLoader`. `DefaultResourceLoader` discovers extensions from `~/.pi/agent/extensions/`, `.pi/extensions/`, and settings.json extension sources.
```typescript
import { createAgentSession, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
import { createAgentSession, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
additionalExtensionPaths: ["/path/to/my-extension.ts"],
@@ -585,7 +585,7 @@ Extensions can register tools, subscribe to events, add commands, and more. See
**Event Bus:** Extensions can communicate via `pi.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";
import { createEventBus, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const eventBus = createEventBus();
const loader = new DefaultResourceLoader({
@@ -605,7 +605,7 @@ import {
createAgentSession,
DefaultResourceLoader,
type Skill,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const customSkill: Skill = {
name: "my-skill",
@@ -631,7 +631,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
### Context Files
```typescript
import { createAgentSession, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
import { createAgentSession, DefaultResourceLoader } from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
agentsFilesOverride: (current) => ({
@@ -655,7 +655,7 @@ import {
createAgentSession,
DefaultResourceLoader,
type PromptTemplate,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const customCommand: PromptTemplate = {
name: "deploy",
@@ -690,7 +690,7 @@ import {
createAgentSessionServices,
getAgentDir,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
// In-memory (no persistence)
const { session } = await createAgentSession({
@@ -784,7 +784,7 @@ sm.createBranchedSession(leafId); // Extract path to new file
### Settings Management
```typescript
import { createAgentSession, SettingsManager, SessionManager } from "@mariozechner/pi-coding-agent";
import { createAgentSession, SettingsManager, SessionManager } from "@earendil-works/pi-coding-agent";
// Default: loads from files (global + project merged)
const { session } = await createAgentSession({
@@ -840,7 +840,7 @@ Use `DefaultResourceLoader` to discover extensions, skills, prompts, themes, and
import {
DefaultResourceLoader,
getAgentDir,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const loader = new DefaultResourceLoader({
cwd,
@@ -881,7 +881,7 @@ interface LoadExtensionsResult {
## Complete Example
```typescript
import { getModel } from "@mariozechner/pi-ai";
import { getModel } from "@earendil-works/pi-ai";
import { Type } from "typebox";
import {
AuthStorage,
@@ -893,7 +893,7 @@ import {
readTool,
SessionManager,
SettingsManager,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
// Set up auth storage (custom location)
const authStorage = AuthStorage.create("/custom/agent/auth.json");
@@ -978,7 +978,7 @@ import {
getAgentDir,
InteractiveMode,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
@@ -1018,7 +1018,7 @@ import {
getAgentDir,
runPrintMode,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });
@@ -1055,7 +1055,7 @@ import {
getAgentDir,
runRpcMode,
SessionManager,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => {
const services = await createAgentSessionServices({ cwd });

View File

@@ -28,13 +28,13 @@ 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)):
- [`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
Source on GitHub ([pi-mono](https://github.com/earendil-works/pi-mono)):
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/earendil-works/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/earendil-works/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/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
- [`packages/agent/src/types.ts`](https://github.com/earendil-works/pi-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/@earendil-works/pi-coding-agent/dist/` and `node_modules/@earendil-works/pi-ai/dist/`.
## Message Types

View File

@@ -17,7 +17,7 @@ pkg update && pkg upgrade
pkg install nodejs termux-api git
# Install pi
npm install -g @mariozechner/pi-coding-agent
npm install -g @earendil-works/pi-coding-agent
# Create config directory
mkdir -p ~/.pi/agent

View File

@@ -52,7 +52,7 @@ vim ~/.pi/agent/themes/my-theme.json
```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/earendil-works/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"primary": "#00aaff",
@@ -122,7 +122,7 @@ vim ~/.pi/agent/themes/my-theme.json
```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/earendil-works/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"blue": "#0066cc",

View File

@@ -4,7 +4,7 @@
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:** [`@earendil-works/pi-tui`](https://github.com/earendil-works/pi-mono/tree/main/packages/tui)
## Component Interface
@@ -33,7 +33,7 @@ The TUI appends a full SGR reset and OSC 8 reset at the end of each rendered lin
Components that display a text cursor and need IME (Input Method Editor) support should implement the `Focusable` interface:
```typescript
import { CURSOR_MARKER, type Component, type Focusable } from "@mariozechner/pi-tui";
import { CURSOR_MARKER, type Component, type Focusable } from "@earendil-works/pi-tui";
class MyInput implements Component, Focusable {
focused: boolean = false; // Set by TUI when focus changes
@@ -59,7 +59,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 "@earendil-works/pi-tui";
class SearchDialog extends Container implements Focusable {
private searchInput: Input;
@@ -179,10 +179,10 @@ See [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for compre
## Built-in Components
Import from `@mariozechner/pi-tui`:
Import from `@earendil-works/pi-tui`:
```typescript
import { Text, Box, Container, Spacer, Markdown } from "@mariozechner/pi-tui";
import { Text, Box, Container, Spacer, Markdown } from "@earendil-works/pi-tui";
```
### Text
@@ -264,7 +264,7 @@ const image = new Image(
Use `matchesKey()` for key detection:
```typescript
import { matchesKey, Key } from "@mariozechner/pi-tui";
import { matchesKey, Key } from "@earendil-works/pi-tui";
handleInput(data: string) {
if (matchesKey(data, Key.up)) {
@@ -290,7 +290,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 "@earendil-works/pi-tui";
render(width: number): string[] {
// Truncate long lines
@@ -311,7 +311,7 @@ Example: Interactive selector
import {
matchesKey, Key,
truncateToWidth, visibleWidth
} from "@mariozechner/pi-tui";
} from "@earendil-works/pi-tui";
class MySelector {
private items: string[];
@@ -425,8 +425,8 @@ renderResult(result, options, theme, context) {
**For Markdown**, use `getMarkdownTheme()`:
```typescript
import { getMarkdownTheme } from "@mariozechner/pi-coding-agent";
import { Markdown } from "@mariozechner/pi-tui";
import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
import { Markdown } from "@earendil-works/pi-tui";
renderResult(result, options, theme, context) {
const mdTheme = getMarkdownTheme();
@@ -587,12 +587,12 @@ 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 `@earendil-works/pi-tui` with `DynamicBorder` for framing.
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { DynamicBorder } from "@mariozechner/pi-coding-agent";
import { Container, type SelectItem, SelectList, Text } from "@mariozechner/pi-tui";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
import { Container, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
pi.registerCommand("pick", {
handler: async (_args, ctx) => {
@@ -650,7 +650,7 @@ 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 "@earendil-works/pi-coding-agent";
pi.registerCommand("fetch", {
handler: async (_args, ctx) => {
@@ -679,11 +679,11 @@ 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 `@earendil-works/pi-tui` with `getSettingsListTheme()`.
```typescript
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
import { Container, type SettingItem, SettingsList, Text } from "@mariozechner/pi-tui";
import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
import { Container, type SettingItem, SettingsList, Text } from "@earendil-works/pi-tui";
pi.registerCommand("settings", {
handler: async (_args, ctx) => {
@@ -822,8 +822,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 "@earendil-works/pi-coding-agent";
import { matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
type Mode = "normal" | "insert";

View File

@@ -137,7 +137,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
See [docs/extensions.md](../../docs/extensions.md) for full documentation.
```typescript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
export default function (pi: ExtensionAPI) {
@@ -179,7 +179,7 @@ export default function (pi: ExtensionAPI) {
**Use StringEnum for string parameters** (required for Google API compatibility):
```typescript
import { StringEnum } from "@mariozechner/pi-ai";
import { StringEnum } from "@earendil-works/pi-ai";
// Good
action: StringEnum(["list", "add"] as const)

View File

@@ -5,7 +5,7 @@
* Uses the last assistant message to generate a commit message.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("session_shutdown", async (_event, ctx) => {

View File

@@ -7,8 +7,8 @@
* pi -e ./bash-spawn-hook.ts
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { createBashTool } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { createBashTool } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
const cwd = process.cwd();

View File

@@ -7,7 +7,7 @@
* Usage: /bookmark [label] - bookmark the last assistant message
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.registerCommand("bookmark", {

View File

@@ -3,9 +3,9 @@ import {
type ExtensionAPI,
type ExtensionContext,
type KeybindingsManager,
} from "@mariozechner/pi-coding-agent";
import type { Component, EditorTheme, TUI } from "@mariozechner/pi-tui";
import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
} from "@earendil-works/pi-coding-agent";
import type { Component, EditorTheme, TUI } from "@earendil-works/pi-tui";
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
function fitBorder(
left: string,

View File

@@ -25,9 +25,9 @@
* pi -e ./built-in-tool-renderer.ts
*/
import type { BashToolDetails, EditToolDetails, ExtensionAPI, ReadToolDetails } from "@mariozechner/pi-coding-agent";
import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@mariozechner/pi-coding-agent";
import { Text } from "@mariozechner/pi-tui";
import type { BashToolDetails, EditToolDetails, ExtensionAPI, ReadToolDetails } from "@earendil-works/pi-coding-agent";
import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@earendil-works/pi-coding-agent";
import { Text } from "@earendil-works/pi-tui";
export default function (pi: ExtensionAPI) {
const cwd = process.cwd();

View File

@@ -19,7 +19,7 @@
import * as fs from "node:fs";
import * as path from "node:path";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
/**
* Recursively find all .md files in a directory

View File

@@ -10,7 +10,7 @@
* 3. Use /commands extensions to filter by source
*/
import type { ExtensionAPI, SlashCommandInfo } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, SlashCommandInfo } from "@earendil-works/pi-coding-agent";
export default function commandsExtension(pi: ExtensionAPI) {
pi.registerCommand("commands", {

View File

@@ -5,7 +5,7 @@
* Demonstrates how to cancel session events using the before_* events.
*/
import type { ExtensionAPI, SessionBeforeSwitchEvent, SessionMessageEntry } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, SessionBeforeSwitchEvent, SessionMessageEntry } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("session_before_switch", async (event: SessionBeforeSwitchEvent, ctx) => {

View File

@@ -13,9 +13,9 @@
* pi --extension examples/extensions/custom-compaction.ts
*/
import { complete } from "@mariozechner/pi-ai";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
import { complete } from "@earendil-works/pi-ai";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("session_before_compact", async (event, ctx) => {

View File

@@ -8,9 +8,9 @@
* Token stats come from ctx.sessionManager/ctx.model (already accessible).
*/
import type { AssistantMessage } from "@mariozechner/pi-ai";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
import type { AssistantMessage } from "@earendil-works/pi-ai";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
export default function (pi: ExtensionAPI) {
let enabled = false;

View File

@@ -5,8 +5,8 @@
* (logo + keybinding hints) with a custom component showing the pi mascot.
*/
import type { ExtensionAPI, Theme } from "@mariozechner/pi-coding-agent";
import { VERSION } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, Theme } from "@earendil-works/pi-coding-agent";
import { VERSION } from "@earendil-works/pi-coding-agent";
// --- PI MASCOT ---
// Based on pi_mascot.ts - the pi agent character

View File

@@ -42,8 +42,8 @@ import {
type Tool,
type ToolCall,
type ToolResultMessage,
} from "@mariozechner/pi-ai";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-ai";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// =============================================================================
// OAuth Implementation (copied from packages/ai/src/utils/oauth/anthropic.ts)

View File

@@ -20,8 +20,8 @@ import {
type SimpleStreamOptions,
streamSimpleAnthropic,
streamSimpleOpenAIResponses,
} from "@mariozechner/pi-ai";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-ai";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// =============================================================================
// Constants

View File

@@ -8,7 +8,7 @@
* npx tsx test.ts claude-sonnet-4-5-20250929 --thinking
*/
import { type Api, type Context, type Model, registerApiProvider, streamSimple } from "@mariozechner/pi-ai";
import { type Api, type Context, type Model, registerApiProvider, streamSimple } from "@earendil-works/pi-ai";
import { readFileSync } from "fs";
import { getAgentDir } from "packages/coding-agent/src/config.js";
import { join } from "path";

View File

@@ -5,7 +5,7 @@
* Useful to ensure work is committed before switching context.
*/
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
async function checkDirtyRepo(
pi: ExtensionAPI,

View File

@@ -5,8 +5,8 @@
* Height is calculated from width to maintain DOOM's aspect ratio.
*/
import type { Component } from "@mariozechner/pi-tui";
import { isKeyRelease, type TUI } from "@mariozechner/pi-tui";
import type { Component } from "@earendil-works/pi-tui";
import { isKeyRelease, type TUI } from "@earendil-works/pi-tui";
import type { DoomEngine } from "./doom-engine.js";
import { DoomKeys, mapKeyToDoom } from "./doom-keys.js";

View File

@@ -34,7 +34,7 @@ export const DoomKeys = {
KEY_RALT: 0x80 + 0x38,
} as const;
import { Key, matchesKey, parseKey } from "@mariozechner/pi-tui";
import { Key, matchesKey, parseKey } from "@earendil-works/pi-tui";
/**
* Map terminal key input to DOOM key codes

View File

@@ -9,7 +9,7 @@
* This demonstrates that overlays can handle real-time game rendering at 35 FPS.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { DoomOverlayComponent } from "./doom-component.js";
import { DoomEngine } from "./doom-engine.js";
import { ensureWadFile } from "./wad-finder.js";

View File

@@ -1,5 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"$schema": "https://raw.githubusercontent.com/earendil-works/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "dynamic-resources",
"vars": {
"cyan": "#00d7ff",

View File

@@ -1,6 +1,6 @@
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const baseDir = dirname(fileURLToPath(import.meta.url));

View File

@@ -7,7 +7,7 @@
* - Registers additional tools at runtime via /add-echo-tool <name>
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
const ECHO_PARAMS = Type.Object({

View File

@@ -7,7 +7,7 @@
* Usage: /emit [event-name] [data] - emit an event on the bus
*/
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// Store ctx for use in event handler

View File

@@ -9,7 +9,7 @@
*/
import * as fs from "node:fs";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("session_start", async (_event, ctx) => {

View File

@@ -5,7 +5,7 @@
* When forking, offers to restore code to that point in history.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
const checkpoints = new Map<string, string>();

View File

@@ -1,13 +1,13 @@
// Requires GitHub CLI (`gh`) and a GitHub repository checkout.
// Preloads the latest open issues once per session, then filters them locally for fast `#...` completion.
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import {
type AutocompleteItem,
type AutocompleteProvider,
type AutocompleteSuggestions,
fuzzyFilter,
} from "@mariozechner/pi-tui";
} from "@earendil-works/pi-tui";
type GitHubIssue = {
number: number;

View File

@@ -12,10 +12,10 @@
* The generated prompt appears as a draft in the editor for review/editing.
*/
import type { AgentMessage } from "@mariozechner/pi-agent-core";
import { complete, type Message } from "@mariozechner/pi-ai";
import type { ExtensionAPI, SessionEntry } from "@mariozechner/pi-coding-agent";
import { BorderedLoader, convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
import type { AgentMessage } from "@earendil-works/pi-agent-core";
import { complete, type Message } from "@earendil-works/pi-ai";
import type { ExtensionAPI, SessionEntry } from "@earendil-works/pi-coding-agent";
import { BorderedLoader, convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
const SYSTEM_PROMPT = `You are a context transfer assistant. Given a conversation history and the user's goal for a new thread, generate a focused prompt that:

View File

@@ -2,8 +2,8 @@
* Hello Tool - Minimal custom tool example
*/
import { Type } from "@mariozechner/pi-ai";
import { defineTool, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Type } from "@earendil-works/pi-ai";
import { defineTool, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
const helloTool = defineTool({
name: "hello",

View File

@@ -18,7 +18,7 @@
* /thinking-label Reset to the default label
*/
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
const DEFAULT_LABEL = "Pondering...";

View File

@@ -14,7 +14,7 @@
*
* Note: Regular !command syntax (whole-line bash) is preserved and works as before.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
const PATTERN = /!\{([^}]+)\}/g;

View File

@@ -9,7 +9,7 @@
* ping → "pong" (instant, no LLM)
* time → current time (instant, no LLM)
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("input", async (event, ctx) => {

View File

@@ -21,7 +21,7 @@
*/
import { spawnSync } from "node:child_process";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// Default interactive commands - editors, pagers, git ops, TUIs
const DEFAULT_INTERACTIVE_COMMANDS = [

View File

@@ -7,7 +7,7 @@
import { exec } from "node:child_process";
import { promisify } from "node:util";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const execAsync = promisify(exec);

View File

@@ -7,8 +7,8 @@
* Usage: /status [message] - sends a status message with custom rendering
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Box, Text } from "@mariozechner/pi-tui";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Box, Text } from "@earendil-works/pi-tui";
export default function (pi: ExtensionAPI) {
// Register custom renderer for "status-update" messages

View File

@@ -16,7 +16,7 @@
* Then use ctrl+o to toggle between minimal (collapsed) and full (expanded) views.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import {
createBashTool,
createEditTool,
@@ -25,8 +25,8 @@ import {
createLsTool,
createReadTool,
createWriteTool,
} from "@mariozechner/pi-coding-agent";
import { Text } from "@mariozechner/pi-tui";
} from "@earendil-works/pi-coding-agent";
import { Text } from "@earendil-works/pi-tui";
import { homedir } from "os";
/**

View File

@@ -9,8 +9,8 @@
* - ctrl+c, ctrl+d, etc. work in both modes
*/
import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { matchesKey, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
// Normal mode key mappings: key -> escape sequence (or null for mode switch)
const NORMAL_KEYS: Record<string, string | null> = {

View File

@@ -7,7 +7,7 @@
* Usage: pi -e ./model-status.ts
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("model_select", async (event, ctx) => {

View File

@@ -8,7 +8,7 @@
* - Windows toast: Windows Terminal (WSL)
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
function windowsToastScript(title: string, body: string): string {
const type = "Windows.UI.Notifications";

View File

@@ -19,9 +19,9 @@
* /overlay-streaming - Multiple input panels with simulated streaming (Tab to cycle focus)
*/
import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@mariozechner/pi-coding-agent";
import type { Component, OverlayAnchor, OverlayHandle, OverlayOptions, TUI } from "@mariozechner/pi-tui";
import { matchesKey, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@earendil-works/pi-coding-agent";
import type { Component, OverlayAnchor, OverlayHandle, OverlayOptions, TUI } from "@earendil-works/pi-tui";
import { matchesKey, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
import { spawn } from "child_process";
// Global handle for toggle demo (in real code, use a more elegant pattern)

View File

@@ -8,8 +8,8 @@
* - Edge case tests (wide chars, styled text, emoji)
*/
import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@mariozechner/pi-coding-agent";
import { CURSOR_MARKER, type Focusable, matchesKey, visibleWidth } from "@mariozechner/pi-tui";
import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@earendil-works/pi-coding-agent";
import { CURSOR_MARKER, type Focusable, matchesKey, visibleWidth } from "@earendil-works/pi-tui";
export default function (pi: ExtensionAPI) {
pi.registerCommand("overlay-test", {

View File

@@ -5,7 +5,7 @@
* Patterns checked: rm -rf, sudo, chmod/chown 777
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
const dangerousPatterns = [/\brm\s+(-rf?|--recursive)/i, /\bsudo\b/i, /\b(chmod|chown)\b.*777/i];

View File

@@ -10,7 +10,7 @@
* 3. When enabled, the agent will respond like a pirate
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function pirateExtension(pi: ExtensionAPI) {
let pirateMode = false;

View File

@@ -12,10 +12,10 @@
* - Progress tracking widget during execution
*/
import type { AgentMessage } from "@mariozechner/pi-agent-core";
import type { AssistantMessage, TextContent } from "@mariozechner/pi-ai";
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import { Key } from "@mariozechner/pi-tui";
import type { AgentMessage } from "@earendil-works/pi-agent-core";
import type { AssistantMessage, TextContent } from "@earendil-works/pi-ai";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import { Key } from "@earendil-works/pi-tui";
import { extractTodoItems, isSafeCommand, markCompletedSteps, type TodoItem } from "./utils.js";
// Tools

View File

@@ -40,10 +40,10 @@
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import type { Api, Model } from "@mariozechner/pi-ai";
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import { DynamicBorder, getAgentDir } from "@mariozechner/pi-coding-agent";
import { Container, Key, type SelectItem, SelectList, Text } from "@mariozechner/pi-tui";
import type { Api, Model } from "@earendil-works/pi-ai";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
import { DynamicBorder, getAgentDir } from "@earendil-works/pi-coding-agent";
import { Container, Key, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
// Preset configuration
interface Preset {

View File

@@ -12,7 +12,7 @@
* 2. Use the extension — it automatically adapts to your active tools and skills
*/
import type { BuildSystemPromptOptions, ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { BuildSystemPromptOptions, ExtensionAPI } from "@earendil-works/pi-coding-agent";
/**
* Adds tool-specific guidance that adapts to the active tool set.

View File

@@ -5,7 +5,7 @@
* Useful for preventing accidental modifications to sensitive files.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
const protectedPaths = [".env", ".git/", "node_modules/"];

View File

@@ -1,6 +1,6 @@
import { appendFileSync } from "node:fs";
import { join } from "node:path";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
const logFile = join(process.cwd(), ".pi", "provider-payload.log");

View File

@@ -7,9 +7,9 @@
* 3. Loads the result into the editor for user to fill in answers
*/
import { complete, type UserMessage } from "@mariozechner/pi-ai";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { BorderedLoader } from "@mariozechner/pi-coding-agent";
import { complete, type UserMessage } from "@earendil-works/pi-ai";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { BorderedLoader } from "@earendil-works/pi-coding-agent";
const SYSTEM_PROMPT = `You are a question extractor. Given text from a conversation, extract any questions that need answering and format them for the user to fill in.

View File

@@ -4,8 +4,8 @@
* Escape in editor returns to options, Escape in options cancels
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth } from "@mariozechner/pi-tui";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth } from "@earendil-works/pi-tui";
import { Type } from "typebox";
interface OptionWithDesc {

View File

@@ -5,8 +5,8 @@
* Multiple questions: tab bar navigation between questions
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth } from "@mariozechner/pi-tui";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth } from "@earendil-works/pi-tui";
import { Type } from "typebox";
// Types

View File

@@ -4,7 +4,7 @@
* Usage: pi --extension ./examples/extensions/rainbow-editor.ts
*/
import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { CustomEditor, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
// Base colors (coral → yellow → green → teal → blue → purple → pink)
const COLORS: [number, number, number][] = [

View File

@@ -5,7 +5,7 @@
* tool that queues a follow-up command to trigger reload.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
export default function (pi: ExtensionAPI) {

View File

@@ -17,7 +17,7 @@
* - setEditorText() - via /rpc-prefill command
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
let turnCount = 0;

View File

@@ -45,8 +45,8 @@ import { spawn } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { SandboxManager, type SandboxRuntimeConfig } from "@anthropic-ai/sandbox-runtime";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { type BashOperations, createBashTool, getAgentDir } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { type BashOperations, createBashTool, getAgentDir } from "@earendil-works/pi-coding-agent";
interface SandboxConfig extends SandboxRuntimeConfig {
enabled?: boolean;

View File

@@ -11,7 +11,7 @@
* /followup And then? - Sends while streaming with followUp delivery
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// Simple command that sends a user message

View File

@@ -7,7 +7,7 @@
* Usage: /session-name [name] - set or show session name
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.registerCommand("session-name", {

View File

@@ -5,7 +5,7 @@
* Demonstrates how extensions can use ctx.shutdown() to exit pi cleanly.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
export default function (pi: ExtensionAPI) {

View File

@@ -2,8 +2,8 @@
* Snake game extension - play snake with /snake command
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { matchesKey, visibleWidth } from "@mariozechner/pi-tui";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { matchesKey, visibleWidth } from "@earendil-works/pi-tui";
const GAME_WIDTH = 40;
const GAME_HEIGHT = 15;

View File

@@ -3,8 +3,8 @@
* Uses Kitty keyboard protocol for smooth movement (press/release detection)
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { isKeyRelease, Key, matchesKey, visibleWidth } from "@mariozechner/pi-tui";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { isKeyRelease, Key, matchesKey, visibleWidth } from "@earendil-works/pi-tui";
const GAME_WIDTH = 60;
const GAME_HEIGHT = 24;

View File

@@ -14,7 +14,7 @@
*/
import { spawn } from "node:child_process";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import {
type BashOperations,
createBashTool,
@@ -24,7 +24,7 @@ import {
type EditOperations,
type ReadOperations,
type WriteOperations,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
function sshExec(remote: string, command: string): Promise<Buffer> {
return new Promise((resolve, reject) => {

View File

@@ -5,7 +5,7 @@
* Shows turn progress with themed colors.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
let turnCount = 0;

View File

@@ -5,8 +5,8 @@
* without paying for an extra follow-up LLM turn.
*/
import { defineTool, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Text } from "@mariozechner/pi-tui";
import { defineTool, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Text } from "@earendil-works/pi-tui";
import { Type } from "typebox";
interface StructuredOutputDetails {

View File

@@ -4,7 +4,7 @@
import * as fs from "node:fs";
import * as path from "node:path";
import { getAgentDir, parseFrontmatter } from "@mariozechner/pi-coding-agent";
import { getAgentDir, parseFrontmatter } from "@earendil-works/pi-coding-agent";
export type AgentScope = "user" | "project" | "both";

View File

@@ -16,11 +16,11 @@ import { spawn } from "node:child_process";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { Message } from "@mariozechner/pi-ai";
import { StringEnum } from "@mariozechner/pi-ai";
import { type ExtensionAPI, getMarkdownTheme, withFileMutationQueue } from "@mariozechner/pi-coding-agent";
import { Container, Markdown, Spacer, Text } from "@mariozechner/pi-tui";
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
import type { Message } from "@earendil-works/pi-ai";
import { StringEnum } from "@earendil-works/pi-ai";
import { type ExtensionAPI, getMarkdownTheme, withFileMutationQueue } from "@earendil-works/pi-coding-agent";
import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
import { Type } from "typebox";
import { type AgentConfig, type AgentScope, discoverAgents } from "./agents.js";

View File

@@ -1,7 +1,7 @@
import { complete, getModel } from "@mariozechner/pi-ai";
import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
import { DynamicBorder, getMarkdownTheme } from "@mariozechner/pi-coding-agent";
import { Container, Markdown, matchesKey, Text } from "@mariozechner/pi-tui";
import { complete, getModel } from "@earendil-works/pi-ai";
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
import { DynamicBorder, getMarkdownTheme } from "@earendil-works/pi-coding-agent";
import { Container, Markdown, matchesKey, Text } from "@earendil-works/pi-tui";
type ContentBlock = {
type?: string;

View File

@@ -3,7 +3,7 @@
*
* Demonstrates ctx.getSystemPrompt() for accessing the effective system prompt.
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("agent_start", (_event, ctx) => {

View File

@@ -17,9 +17,9 @@
* separate variables. Only the agent cursor is ever exposed to the agent.
*/
import { StringEnum } from "@mariozechner/pi-ai";
import type { ExtensionAPI, ExtensionContext, Theme, ToolExecutionMode } from "@mariozechner/pi-coding-agent";
import { type Component, matchesKey, Text, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
import { StringEnum } from "@earendil-works/pi-ai";
import type { ExtensionAPI, ExtensionContext, Theme, ToolExecutionMode } from "@earendil-works/pi-coding-agent";
import { type Component, matchesKey, Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
import { Type } from "typebox";
// Thrown from the tool on illegal actions. The agent runtime surfaces thrown

View File

@@ -7,7 +7,7 @@
* - /timed-signal - Shows confirm using AbortSignal (manual approach)
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// Simple approach: use timeout option (recommended)

View File

@@ -9,7 +9,7 @@
*/
import path from "node:path";
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
const BRAILLE_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];

View File

@@ -10,9 +10,9 @@
* correct for that point in history.
*/
import { StringEnum } from "@mariozechner/pi-ai";
import type { ExtensionAPI, ExtensionContext, Theme } from "@mariozechner/pi-coding-agent";
import { matchesKey, Text, truncateToWidth } from "@mariozechner/pi-tui";
import { StringEnum } from "@earendil-works/pi-ai";
import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-coding-agent";
import { matchesKey, Text, truncateToWidth } from "@earendil-works/pi-tui";
import { Type } from "typebox";
interface Todo {

View File

@@ -20,8 +20,8 @@
* pi -e ./tool-override.ts
*/
import type { TextContent } from "@mariozechner/pi-ai";
import { type ExtensionAPI, getAgentDir, withFileMutationQueue } from "@mariozechner/pi-coding-agent";
import type { TextContent } from "@earendil-works/pi-ai";
import { type ExtensionAPI, getAgentDir, withFileMutationQueue } from "@earendil-works/pi-coding-agent";
import { constants, readFileSync } from "fs";
import { access, appendFile, readFile } from "fs/promises";
import { join, resolve } from "path";

View File

@@ -9,9 +9,9 @@
* 2. Use /tools to open the tool selector
*/
import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@mariozechner/pi-coding-agent";
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
import { Container, type SettingItem, SettingsList } from "@mariozechner/pi-tui";
import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@earendil-works/pi-coding-agent";
import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
import { Container, type SettingItem, SettingsList } from "@earendil-works/pi-tui";
// State persisted to session
interface ToolsState {

View File

@@ -1,4 +1,4 @@
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
const COMPACT_THRESHOLD_TOKENS = 100_000;

View File

@@ -15,7 +15,7 @@
*/
import { mkdtemp, writeFile } from "node:fs/promises";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import {
DEFAULT_MAX_BYTES,
DEFAULT_MAX_LINES,
@@ -23,8 +23,8 @@ import {
type TruncationResult,
truncateHead,
withFileMutationQueue,
} from "@mariozechner/pi-coding-agent";
import { Text } from "@mariozechner/pi-tui";
} from "@earendil-works/pi-coding-agent";
import { Text } from "@earendil-works/pi-tui";
import { execSync } from "child_process";
import { tmpdir } from "os";
import { join } from "path";

View File

@@ -1,4 +1,4 @@
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function widgetPlacementExtension(pi: ExtensionAPI) {
pi.on("session_start", (_event, ctx) => {

View File

@@ -5,7 +5,7 @@
* Requires: npm install in this directory
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import ms from "ms";
import { Type } from "typebox";

View File

@@ -16,7 +16,7 @@
* /working-indicator reset Restore pi's default spinner
*/
import type { ExtensionAPI, ExtensionContext, WorkingIndicatorOptions } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI, ExtensionContext, WorkingIndicatorOptions } from "@earendil-works/pi-coding-agent";
type WorkingIndicatorMode = "dot" | "none" | "pulse" | "spinner" | "default";

View File

@@ -12,7 +12,7 @@
* loader appears, not revert to the default gray "Working...".
*/
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const CUSTOM_MESSAGE = "\x1b[38;2;155;86;63mWorking... (custom)\x1b[39m";
const CUSTOM_INDICATOR = { frames: ["\x1b[38;2;155;86;63m●\x1b[39m"] };

View File

@@ -18,7 +18,7 @@ import { spawn } from "node:child_process";
import { dirname, join } from "node:path";
import * as readline from "node:readline";
import { fileURLToPath } from "node:url";
import { type Component, Container, Input, matchesKey, ProcessTerminal, SelectList, TUI } from "@mariozechner/pi-tui";
import { type Component, Container, Input, matchesKey, ProcessTerminal, SelectList, TUI } from "@earendil-works/pi-tui";
const __dirname = dirname(fileURLToPath(import.meta.url));

View File

@@ -5,7 +5,7 @@
* from cwd and ~/.pi/agent. Model chosen from settings or first available.
*/
import { createAgentSession } from "@mariozechner/pi-coding-agent";
import { createAgentSession } from "@earendil-works/pi-coding-agent";
const { session } = await createAgentSession();

View File

@@ -4,8 +4,8 @@
* Shows how to select a specific model and thinking level.
*/
import { getModel } from "@mariozechner/pi-ai";
import { AuthStorage, createAgentSession, ModelRegistry } from "@mariozechner/pi-coding-agent";
import { getModel } from "@earendil-works/pi-ai";
import { AuthStorage, createAgentSession, ModelRegistry } from "@earendil-works/pi-coding-agent";
// Set up auth storage and model registry
const authStorage = AuthStorage.create();

View File

@@ -4,7 +4,12 @@
* Shows how to replace or modify the default system prompt.
*/
import { createAgentSession, DefaultResourceLoader, getAgentDir, SessionManager } from "@mariozechner/pi-coding-agent";
import {
createAgentSession,
DefaultResourceLoader,
getAgentDir,
SessionManager,
} from "@earendil-works/pi-coding-agent";
const cwd = process.cwd();
const agentDir = getAgentDir();

View File

@@ -12,7 +12,7 @@ import {
getAgentDir,
SessionManager,
type Skill,
} from "@mariozechner/pi-coding-agent";
} from "@earendil-works/pi-coding-agent";
// Or define custom skills inline
const customSkill: Skill = {

Some files were not shown because too many files have changed in this diff Show More