@draht/coding-agent 2026.3.2-2 → 2026.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -6
- package/docs/compaction.md +2 -2
- package/docs/custom-provider.md +3 -3
- package/docs/extensions.md +24 -24
- package/docs/packages.md +1 -1
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +24 -24
- package/docs/session.md +1 -1
- package/docs/termux.md +1 -1
- package/docs/tui.md +20 -20
- package/examples/extensions/README.md +2 -2
- package/examples/sdk/README.md +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# 🏖️ OSS Vacation
|
|
2
|
+
|
|
3
|
+
**Issue tracker and PRs reopen March 2, 2026.**
|
|
4
|
+
|
|
5
|
+
All PRs will be auto-closed until then. Approved contributors can submit PRs after vacation without reapproval. For support, join [Discord](https://discord.com/invite/3cU7Bz4UPx).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
<p align="center">
|
|
2
10
|
<a href="https://shittycodingagent.ai">
|
|
3
11
|
<img src="https://shittycodingagent.ai/logo.svg" alt="pi logo" width="128">
|
|
@@ -5,7 +13,7 @@
|
|
|
5
13
|
</p>
|
|
6
14
|
<p align="center">
|
|
7
15
|
<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>
|
|
8
|
-
<a href="https://www.npmjs.com/package/@
|
|
16
|
+
<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>
|
|
9
17
|
<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>
|
|
10
18
|
</p>
|
|
11
19
|
<p align="center">
|
|
@@ -49,7 +57,7 @@ Pi runs in four modes: interactive, print or JSON, RPC for process integration,
|
|
|
49
57
|
## Quick Start
|
|
50
58
|
|
|
51
59
|
```bash
|
|
52
|
-
npm install -g @
|
|
60
|
+
npm install -g @mariozechner/pi-coding-agent
|
|
53
61
|
```
|
|
54
62
|
|
|
55
63
|
Authenticate with an API key:
|
|
@@ -373,7 +381,7 @@ See [docs/packages.md](docs/packages.md).
|
|
|
373
381
|
### SDK
|
|
374
382
|
|
|
375
383
|
```typescript
|
|
376
|
-
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@
|
|
384
|
+
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@mariozechner/pi-coding-agent";
|
|
377
385
|
|
|
378
386
|
const { session } = await createAgentSession({
|
|
379
387
|
sessionManager: SessionManager.inMemory(),
|
|
@@ -561,6 +569,6 @@ MIT
|
|
|
561
569
|
|
|
562
570
|
## See Also
|
|
563
571
|
|
|
564
|
-
- [@
|
|
565
|
-
- [@
|
|
566
|
-
- [@
|
|
572
|
+
- [@mariozechner/pi-ai](https://www.npmjs.com/package/@mariozechner/pi-ai): Core LLM toolkit
|
|
573
|
+
- [@mariozechner/pi-agent](https://www.npmjs.com/package/@mariozechner/pi-agent): Agent framework
|
|
574
|
+
- [@mariozechner/pi-tui](https://www.npmjs.com/package/@mariozechner/pi-tui): Terminal UI components
|
package/docs/compaction.md
CHANGED
|
@@ -9,7 +9,7 @@ LLMs have limited context windows. When conversations grow too long, pi uses com
|
|
|
9
9
|
- [`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`)
|
|
10
10
|
- [`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
|
|
11
11
|
|
|
12
|
-
For TypeScript definitions in your project, inspect `node_modules/@
|
|
12
|
+
For TypeScript definitions in your project, inspect `node_modules/@mariozechner/pi-coding-agent/dist/`.
|
|
13
13
|
|
|
14
14
|
## Overview
|
|
15
15
|
|
|
@@ -305,7 +305,7 @@ pi.on("session_before_compact", async (event, ctx) => {
|
|
|
305
305
|
To generate a summary with your own model, convert messages to text using `serializeConversation`:
|
|
306
306
|
|
|
307
307
|
```typescript
|
|
308
|
-
import { convertToLlm, serializeConversation } from "@
|
|
308
|
+
import { convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
|
|
309
309
|
|
|
310
310
|
pi.on("session_before_compact", async (event, ctx) => {
|
|
311
311
|
const { preparation } = event;
|
package/docs/custom-provider.md
CHANGED
|
@@ -31,7 +31,7 @@ See these complete provider examples:
|
|
|
31
31
|
## Quick Reference
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import type { ExtensionAPI } from "@
|
|
34
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
35
35
|
|
|
36
36
|
export default function (pi: ExtensionAPI) {
|
|
37
37
|
// Override baseUrl for existing provider
|
|
@@ -200,7 +200,7 @@ pi.registerProvider("custom-api", {
|
|
|
200
200
|
Add OAuth/SSO authentication that integrates with `/login`:
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
|
-
import type { OAuthCredentials, OAuthLoginCallbacks } from "@
|
|
203
|
+
import type { OAuthCredentials, OAuthLoginCallbacks } from "@mariozechner/pi-ai";
|
|
204
204
|
|
|
205
205
|
pi.registerProvider("corporate-ai", {
|
|
206
206
|
baseUrl: "https://ai.corp.com/v1",
|
|
@@ -312,7 +312,7 @@ import {
|
|
|
312
312
|
type SimpleStreamOptions,
|
|
313
313
|
calculateCost,
|
|
314
314
|
createAssistantMessageEventStream,
|
|
315
|
-
} from "@
|
|
315
|
+
} from "@mariozechner/pi-ai";
|
|
316
316
|
|
|
317
317
|
function streamMyProvider(
|
|
318
318
|
model: Model<any>,
|
package/docs/extensions.md
CHANGED
|
@@ -55,7 +55,7 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
|
|
|
55
55
|
Create `~/.pi/agent/extensions/my-extension.ts`:
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
|
-
import type { ExtensionAPI } from "@
|
|
58
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
59
59
|
import { Type } from "@sinclair/typebox";
|
|
60
60
|
|
|
61
61
|
export default function (pi: ExtensionAPI) {
|
|
@@ -137,10 +137,10 @@ To share extensions via npm or git as pi packages, see [packages.md](packages.md
|
|
|
137
137
|
|
|
138
138
|
| Package | Purpose |
|
|
139
139
|
|---------|---------|
|
|
140
|
-
| `@
|
|
140
|
+
| `@mariozechner/pi-coding-agent` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
|
|
141
141
|
| `@sinclair/typebox` | Schema definitions for tool parameters |
|
|
142
|
-
| `@
|
|
143
|
-
| `@
|
|
142
|
+
| `@mariozechner/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
|
|
143
|
+
| `@mariozechner/pi-tui` | TUI components for custom rendering |
|
|
144
144
|
|
|
145
145
|
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.
|
|
146
146
|
|
|
@@ -151,7 +151,7 @@ Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
|
|
|
151
151
|
An extension exports a default function that receives `ExtensionAPI`:
|
|
152
152
|
|
|
153
153
|
```typescript
|
|
154
|
-
import type { ExtensionAPI } from "@
|
|
154
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
155
155
|
|
|
156
156
|
export default function (pi: ExtensionAPI) {
|
|
157
157
|
// Subscribe to events
|
|
@@ -519,7 +519,7 @@ Use this to update UI elements (status bars, footers) or perform model-specific
|
|
|
519
519
|
Fired before tool executes. **Can block.** Use `isToolCallEventType` to narrow and get typed inputs.
|
|
520
520
|
|
|
521
521
|
```typescript
|
|
522
|
-
import { isToolCallEventType } from "@
|
|
522
|
+
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
523
523
|
|
|
524
524
|
pi.on("tool_call", async (event, ctx) => {
|
|
525
525
|
// event.toolName - "bash", "read", "write", "edit", etc.
|
|
@@ -553,7 +553,7 @@ export type MyToolInput = Static<typeof myToolSchema>;
|
|
|
553
553
|
Use `isToolCallEventType` with explicit type parameters:
|
|
554
554
|
|
|
555
555
|
```typescript
|
|
556
|
-
import { isToolCallEventType } from "@
|
|
556
|
+
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
557
557
|
import type { MyToolInput } from "my-extension";
|
|
558
558
|
|
|
559
559
|
pi.on("tool_call", (event) => {
|
|
@@ -573,7 +573,7 @@ Fired after tool executes. **Can modify result.**
|
|
|
573
573
|
- Handlers can return partial patches (`content`, `details`, or `isError`); omitted fields keep their current values
|
|
574
574
|
|
|
575
575
|
```typescript
|
|
576
|
-
import { isBashToolResult } from "@
|
|
576
|
+
import { isBashToolResult } from "@mariozechner/pi-coding-agent";
|
|
577
577
|
|
|
578
578
|
pi.on("tool_result", async (event, ctx) => {
|
|
579
579
|
// event.toolName, event.toolCallId, event.input
|
|
@@ -843,7 +843,7 @@ Tools run with `ExtensionContext`, so they cannot call `ctx.reload()` directly.
|
|
|
843
843
|
Example tool the LLM can call to trigger reload:
|
|
844
844
|
|
|
845
845
|
```typescript
|
|
846
|
-
import type { ExtensionAPI } from "@
|
|
846
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
847
847
|
import { Type } from "@sinclair/typebox";
|
|
848
848
|
|
|
849
849
|
export default function (pi: ExtensionAPI) {
|
|
@@ -882,7 +882,7 @@ Register a custom tool callable by the LLM. See [Custom Tools](#custom-tools) fo
|
|
|
882
882
|
|
|
883
883
|
```typescript
|
|
884
884
|
import { Type } from "@sinclair/typebox";
|
|
885
|
-
import { StringEnum } from "@
|
|
885
|
+
import { StringEnum } from "@mariozechner/pi-ai";
|
|
886
886
|
|
|
887
887
|
pi.registerTool({
|
|
888
888
|
name: "my_tool",
|
|
@@ -1030,7 +1030,7 @@ pi.registerCommand("stats", {
|
|
|
1030
1030
|
Optional: add argument auto-completion for `/command ...`:
|
|
1031
1031
|
|
|
1032
1032
|
```typescript
|
|
1033
|
-
import type { AutocompleteItem } from "@
|
|
1033
|
+
import type { AutocompleteItem } from "@mariozechner/pi-tui";
|
|
1034
1034
|
|
|
1035
1035
|
pi.registerCommand("deploy", {
|
|
1036
1036
|
description: "Deploy to an environment",
|
|
@@ -1282,8 +1282,8 @@ Note: Some models are idiots and include the @ prefix in tool path arguments. Bu
|
|
|
1282
1282
|
|
|
1283
1283
|
```typescript
|
|
1284
1284
|
import { Type } from "@sinclair/typebox";
|
|
1285
|
-
import { StringEnum } from "@
|
|
1286
|
-
import { Text } from "@
|
|
1285
|
+
import { StringEnum } from "@mariozechner/pi-ai";
|
|
1286
|
+
import { Text } from "@mariozechner/pi-tui";
|
|
1287
1287
|
|
|
1288
1288
|
pi.registerTool({
|
|
1289
1289
|
name: "my_tool",
|
|
@@ -1322,7 +1322,7 @@ pi.registerTool({
|
|
|
1322
1322
|
});
|
|
1323
1323
|
```
|
|
1324
1324
|
|
|
1325
|
-
**Important:** Use `StringEnum` from `@
|
|
1325
|
+
**Important:** Use `StringEnum` from `@mariozechner/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
|
|
1326
1326
|
|
|
1327
1327
|
### Overriding Built-in Tools
|
|
1328
1328
|
|
|
@@ -1359,7 +1359,7 @@ Built-in tool implementations:
|
|
|
1359
1359
|
Built-in tools support pluggable operations for delegating to remote systems (SSH, containers, etc.):
|
|
1360
1360
|
|
|
1361
1361
|
```typescript
|
|
1362
|
-
import { createReadTool, createBashTool, type ReadOperations } from "@
|
|
1362
|
+
import { createReadTool, createBashTool, type ReadOperations } from "@mariozechner/pi-coding-agent";
|
|
1363
1363
|
|
|
1364
1364
|
// Create tool with custom operations
|
|
1365
1365
|
const remoteRead = createReadTool(cwd, {
|
|
@@ -1388,7 +1388,7 @@ pi.registerTool({
|
|
|
1388
1388
|
The bash tool also supports a spawn hook to adjust the command, cwd, or env before execution:
|
|
1389
1389
|
|
|
1390
1390
|
```typescript
|
|
1391
|
-
import { createBashTool } from "@
|
|
1391
|
+
import { createBashTool } from "@mariozechner/pi-coding-agent";
|
|
1392
1392
|
|
|
1393
1393
|
const bashTool = createBashTool(cwd, {
|
|
1394
1394
|
spawnHook: ({ command, cwd, env }) => ({
|
|
@@ -1418,7 +1418,7 @@ import {
|
|
|
1418
1418
|
formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
|
|
1419
1419
|
DEFAULT_MAX_BYTES, // 50KB
|
|
1420
1420
|
DEFAULT_MAX_LINES, // 2000
|
|
1421
|
-
} from "@
|
|
1421
|
+
} from "@mariozechner/pi-coding-agent";
|
|
1422
1422
|
|
|
1423
1423
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
1424
1424
|
const output = await runCommand();
|
|
@@ -1482,7 +1482,7 @@ Tool output is wrapped in a `Box` that handles padding and background. Your rend
|
|
|
1482
1482
|
Renders the tool call (before/during execution):
|
|
1483
1483
|
|
|
1484
1484
|
```typescript
|
|
1485
|
-
import { Text } from "@
|
|
1485
|
+
import { Text } from "@mariozechner/pi-tui";
|
|
1486
1486
|
|
|
1487
1487
|
renderCall(args, theme) {
|
|
1488
1488
|
let text = theme.fg("toolTitle", theme.bold("my_tool "));
|
|
@@ -1526,7 +1526,7 @@ renderResult(result, { expanded, isPartial }, theme) {
|
|
|
1526
1526
|
Use `keyHint()` to display keybinding hints that respect user's keybinding configuration:
|
|
1527
1527
|
|
|
1528
1528
|
```typescript
|
|
1529
|
-
import { keyHint } from "@
|
|
1529
|
+
import { keyHint } from "@mariozechner/pi-coding-agent";
|
|
1530
1530
|
|
|
1531
1531
|
renderResult(result, { expanded }, theme) {
|
|
1532
1532
|
let text = theme.fg("success", "✓ Done");
|
|
@@ -1700,7 +1700,7 @@ ctx.ui.theme.fg("accent", "styled text"); // Access current theme
|
|
|
1700
1700
|
For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
|
|
1701
1701
|
|
|
1702
1702
|
```typescript
|
|
1703
|
-
import { Text, Component } from "@
|
|
1703
|
+
import { Text, Component } from "@mariozechner/pi-tui";
|
|
1704
1704
|
|
|
1705
1705
|
const result = await ctx.ui.custom<boolean>((tui, theme, keybindings, done) => {
|
|
1706
1706
|
const text = new Text("Press Enter to confirm, Escape to cancel", 1, 1);
|
|
@@ -1758,8 +1758,8 @@ See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts]
|
|
|
1758
1758
|
Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
|
|
1759
1759
|
|
|
1760
1760
|
```typescript
|
|
1761
|
-
import { CustomEditor, type ExtensionAPI } from "@
|
|
1762
|
-
import { matchesKey } from "@
|
|
1761
|
+
import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
1762
|
+
import { matchesKey } from "@mariozechner/pi-tui";
|
|
1763
1763
|
|
|
1764
1764
|
class VimEditor extends CustomEditor {
|
|
1765
1765
|
private mode: "normal" | "insert" = "insert";
|
|
@@ -1799,7 +1799,7 @@ See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
|
|
|
1799
1799
|
Register a custom renderer for messages with your `customType`:
|
|
1800
1800
|
|
|
1801
1801
|
```typescript
|
|
1802
|
-
import { Text } from "@
|
|
1802
|
+
import { Text } from "@mariozechner/pi-tui";
|
|
1803
1803
|
|
|
1804
1804
|
pi.registerMessageRenderer("my-extension", (message, options, theme) => {
|
|
1805
1805
|
const { expanded } = options;
|
|
@@ -1848,7 +1848,7 @@ theme.strikethrough(text)
|
|
|
1848
1848
|
For syntax highlighting in custom tool renderers:
|
|
1849
1849
|
|
|
1850
1850
|
```typescript
|
|
1851
|
-
import { highlightCode, getLanguageFromPath } from "@
|
|
1851
|
+
import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
|
|
1852
1852
|
|
|
1853
1853
|
// Highlight code with explicit language
|
|
1854
1854
|
const highlighted = highlightCode("const x = 1;", "typescript", theme);
|
package/docs/packages.md
CHANGED
|
@@ -149,7 +149,7 @@ If no `pi` manifest is present, pi auto-discovers resources from these directori
|
|
|
149
149
|
|
|
150
150
|
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.
|
|
151
151
|
|
|
152
|
-
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: `@
|
|
152
|
+
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`.
|
|
153
153
|
|
|
154
154
|
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.
|
|
155
155
|
|
package/docs/rpc.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
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.
|
|
4
4
|
|
|
5
|
-
**Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@
|
|
5
|
+
**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).
|
|
6
6
|
|
|
7
7
|
## Starting RPC Mode
|
|
8
8
|
|
package/docs/sdk.md
CHANGED
|
@@ -16,7 +16,7 @@ See [examples/sdk/](../examples/sdk/) for working examples from minimal to full
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
|
-
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@
|
|
19
|
+
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@mariozechner/pi-coding-agent";
|
|
20
20
|
|
|
21
21
|
// Set up credential storage and model registry
|
|
22
22
|
const authStorage = AuthStorage.create();
|
|
@@ -40,7 +40,7 @@ await session.prompt("What files are in the current directory?");
|
|
|
40
40
|
## Installation
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
npm install @
|
|
43
|
+
npm install @mariozechner/pi-coding-agent
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
The SDK is included in the main package. No separate installation needed.
|
|
@@ -54,7 +54,7 @@ The main factory function. Creates an `AgentSession` with configurable options.
|
|
|
54
54
|
`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.
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
|
-
import { createAgentSession } from "@
|
|
57
|
+
import { createAgentSession } from "@mariozechner/pi-coding-agent";
|
|
58
58
|
|
|
59
59
|
// Minimal: defaults with DefaultResourceLoader
|
|
60
60
|
const { session } = await createAgentSession();
|
|
@@ -161,7 +161,7 @@ Both `steer()` and `followUp()` expand file-based prompt templates but error on
|
|
|
161
161
|
|
|
162
162
|
### Agent and AgentState
|
|
163
163
|
|
|
164
|
-
The `Agent` class (from `@
|
|
164
|
+
The `Agent` class (from `@mariozechner/pi-agent-core`) handles the core LLM interaction. Access it via `session.agent`.
|
|
165
165
|
|
|
166
166
|
```typescript
|
|
167
167
|
// Access current state
|
|
@@ -282,8 +282,8 @@ When you pass a custom `ResourceLoader`, `cwd` and `agentDir` no longer control
|
|
|
282
282
|
### Model
|
|
283
283
|
|
|
284
284
|
```typescript
|
|
285
|
-
import { getModel } from "@
|
|
286
|
-
import { AuthStorage, ModelRegistry } from "@
|
|
285
|
+
import { getModel } from "@mariozechner/pi-ai";
|
|
286
|
+
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
287
287
|
|
|
288
288
|
const authStorage = AuthStorage.create();
|
|
289
289
|
const modelRegistry = new ModelRegistry(authStorage);
|
|
@@ -330,7 +330,7 @@ API key resolution priority (handled by AuthStorage):
|
|
|
330
330
|
4. Fallback resolver (for custom provider keys from `models.json`)
|
|
331
331
|
|
|
332
332
|
```typescript
|
|
333
|
-
import { AuthStorage, ModelRegistry } from "@
|
|
333
|
+
import { AuthStorage, ModelRegistry } from "@mariozechner/pi-coding-agent";
|
|
334
334
|
|
|
335
335
|
// Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
|
|
336
336
|
const authStorage = AuthStorage.create();
|
|
@@ -366,7 +366,7 @@ const simpleRegistry = new ModelRegistry(authStorage);
|
|
|
366
366
|
Use a `ResourceLoader` to override the system prompt:
|
|
367
367
|
|
|
368
368
|
```typescript
|
|
369
|
-
import { createAgentSession, DefaultResourceLoader } from "@
|
|
369
|
+
import { createAgentSession, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
|
|
370
370
|
|
|
371
371
|
const loader = new DefaultResourceLoader({
|
|
372
372
|
systemPromptOverride: () => "You are a helpful assistant.",
|
|
@@ -386,7 +386,7 @@ import {
|
|
|
386
386
|
readOnlyTools, // read, grep, find, ls
|
|
387
387
|
readTool, bashTool, editTool, writeTool,
|
|
388
388
|
grepTool, findTool, lsTool,
|
|
389
|
-
} from "@
|
|
389
|
+
} from "@mariozechner/pi-coding-agent";
|
|
390
390
|
|
|
391
391
|
// Use built-in tool set
|
|
392
392
|
const { session } = await createAgentSession({
|
|
@@ -414,7 +414,7 @@ import {
|
|
|
414
414
|
createGrepTool,
|
|
415
415
|
createFindTool,
|
|
416
416
|
createLsTool,
|
|
417
|
-
} from "@
|
|
417
|
+
} from "@mariozechner/pi-coding-agent";
|
|
418
418
|
|
|
419
419
|
const cwd = "/path/to/project";
|
|
420
420
|
|
|
@@ -444,7 +444,7 @@ const { session } = await createAgentSession({
|
|
|
444
444
|
|
|
445
445
|
```typescript
|
|
446
446
|
import { Type } from "@sinclair/typebox";
|
|
447
|
-
import { createAgentSession, type ToolDefinition } from "@
|
|
447
|
+
import { createAgentSession, type ToolDefinition } from "@mariozechner/pi-coding-agent";
|
|
448
448
|
|
|
449
449
|
// Inline custom tool
|
|
450
450
|
const myTool: ToolDefinition = {
|
|
@@ -475,7 +475,7 @@ Custom tools passed via `customTools` are combined with extension-registered too
|
|
|
475
475
|
Extensions are loaded by the `ResourceLoader`. `DefaultResourceLoader` discovers extensions from `~/.pi/agent/extensions/`, `.pi/extensions/`, and settings.json extension sources.
|
|
476
476
|
|
|
477
477
|
```typescript
|
|
478
|
-
import { createAgentSession, DefaultResourceLoader } from "@
|
|
478
|
+
import { createAgentSession, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
|
|
479
479
|
|
|
480
480
|
const loader = new DefaultResourceLoader({
|
|
481
481
|
additionalExtensionPaths: ["/path/to/my-extension.ts"],
|
|
@@ -497,7 +497,7 @@ Extensions can register tools, subscribe to events, add commands, and more. See
|
|
|
497
497
|
**Event Bus:** Extensions can communicate via `pi.events`. Pass a shared `eventBus` to `DefaultResourceLoader` if you need to emit or listen from outside:
|
|
498
498
|
|
|
499
499
|
```typescript
|
|
500
|
-
import { createEventBus, DefaultResourceLoader } from "@
|
|
500
|
+
import { createEventBus, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
|
|
501
501
|
|
|
502
502
|
const eventBus = createEventBus();
|
|
503
503
|
const loader = new DefaultResourceLoader({
|
|
@@ -517,7 +517,7 @@ import {
|
|
|
517
517
|
createAgentSession,
|
|
518
518
|
DefaultResourceLoader,
|
|
519
519
|
type Skill,
|
|
520
|
-
} from "@
|
|
520
|
+
} from "@mariozechner/pi-coding-agent";
|
|
521
521
|
|
|
522
522
|
const customSkill: Skill = {
|
|
523
523
|
name: "my-skill",
|
|
@@ -543,7 +543,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
|
|
|
543
543
|
### Context Files
|
|
544
544
|
|
|
545
545
|
```typescript
|
|
546
|
-
import { createAgentSession, DefaultResourceLoader } from "@
|
|
546
|
+
import { createAgentSession, DefaultResourceLoader } from "@mariozechner/pi-coding-agent";
|
|
547
547
|
|
|
548
548
|
const loader = new DefaultResourceLoader({
|
|
549
549
|
agentsFilesOverride: (current) => ({
|
|
@@ -567,7 +567,7 @@ import {
|
|
|
567
567
|
createAgentSession,
|
|
568
568
|
DefaultResourceLoader,
|
|
569
569
|
type PromptTemplate,
|
|
570
|
-
} from "@
|
|
570
|
+
} from "@mariozechner/pi-coding-agent";
|
|
571
571
|
|
|
572
572
|
const customCommand: PromptTemplate = {
|
|
573
573
|
name: "deploy",
|
|
@@ -594,7 +594,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
|
|
|
594
594
|
Sessions use a tree structure with `id`/`parentId` linking, enabling in-place branching.
|
|
595
595
|
|
|
596
596
|
```typescript
|
|
597
|
-
import { createAgentSession, SessionManager } from "@
|
|
597
|
+
import { createAgentSession, SessionManager } from "@mariozechner/pi-coding-agent";
|
|
598
598
|
|
|
599
599
|
// In-memory (no persistence)
|
|
600
600
|
const { session } = await createAgentSession({
|
|
@@ -665,7 +665,7 @@ sm.createBranchedSession(leafId); // Extract path to new file
|
|
|
665
665
|
### Settings Management
|
|
666
666
|
|
|
667
667
|
```typescript
|
|
668
|
-
import { createAgentSession, SettingsManager, SessionManager } from "@
|
|
668
|
+
import { createAgentSession, SettingsManager, SessionManager } from "@mariozechner/pi-coding-agent";
|
|
669
669
|
|
|
670
670
|
// Default: loads from files (global + project merged)
|
|
671
671
|
const { session } = await createAgentSession({
|
|
@@ -721,7 +721,7 @@ Use `DefaultResourceLoader` to discover extensions, skills, prompts, themes, and
|
|
|
721
721
|
import {
|
|
722
722
|
DefaultResourceLoader,
|
|
723
723
|
getAgentDir,
|
|
724
|
-
} from "@
|
|
724
|
+
} from "@mariozechner/pi-coding-agent";
|
|
725
725
|
|
|
726
726
|
const loader = new DefaultResourceLoader({
|
|
727
727
|
cwd,
|
|
@@ -762,7 +762,7 @@ interface LoadExtensionsResult {
|
|
|
762
762
|
## Complete Example
|
|
763
763
|
|
|
764
764
|
```typescript
|
|
765
|
-
import { getModel } from "@
|
|
765
|
+
import { getModel } from "@mariozechner/pi-ai";
|
|
766
766
|
import { Type } from "@sinclair/typebox";
|
|
767
767
|
import {
|
|
768
768
|
AuthStorage,
|
|
@@ -774,7 +774,7 @@ import {
|
|
|
774
774
|
readTool,
|
|
775
775
|
bashTool,
|
|
776
776
|
type ToolDefinition,
|
|
777
|
-
} from "@
|
|
777
|
+
} from "@mariozechner/pi-coding-agent";
|
|
778
778
|
|
|
779
779
|
// Set up auth storage (custom location)
|
|
780
780
|
const authStorage = AuthStorage.create("/custom/agent/auth.json");
|
|
@@ -851,7 +851,7 @@ The SDK exports run mode utilities for building custom interfaces on top of `cre
|
|
|
851
851
|
Full TUI interactive mode with editor, chat history, and all built-in commands:
|
|
852
852
|
|
|
853
853
|
```typescript
|
|
854
|
-
import { createAgentSession, InteractiveMode } from "@
|
|
854
|
+
import { createAgentSession, InteractiveMode } from "@mariozechner/pi-coding-agent";
|
|
855
855
|
|
|
856
856
|
const { session } = await createAgentSession({ /* ... */ });
|
|
857
857
|
|
|
@@ -872,7 +872,7 @@ await mode.run(); // Blocks until exit
|
|
|
872
872
|
Single-shot mode: send prompts, output result, exit:
|
|
873
873
|
|
|
874
874
|
```typescript
|
|
875
|
-
import { createAgentSession, runPrintMode } from "@
|
|
875
|
+
import { createAgentSession, runPrintMode } from "@mariozechner/pi-coding-agent";
|
|
876
876
|
|
|
877
877
|
const { session } = await createAgentSession({ /* ... */ });
|
|
878
878
|
|
|
@@ -889,7 +889,7 @@ await runPrintMode(session, {
|
|
|
889
889
|
JSON-RPC mode for subprocess integration:
|
|
890
890
|
|
|
891
891
|
```typescript
|
|
892
|
-
import { createAgentSession, runRpcMode } from "@
|
|
892
|
+
import { createAgentSession, runRpcMode } from "@mariozechner/pi-coding-agent";
|
|
893
893
|
|
|
894
894
|
const { session } = await createAgentSession({ /* ... */ });
|
|
895
895
|
|
package/docs/session.md
CHANGED
|
@@ -34,7 +34,7 @@ Source on GitHub ([pi-mono](https://github.com/badlogic/pi-mono)):
|
|
|
34
34
|
- [`packages/ai/src/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
|
|
35
35
|
- [`packages/agent/src/types.ts`](https://github.com/badlogic/pi-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
|
|
36
36
|
|
|
37
|
-
For TypeScript definitions in your project, inspect `node_modules/@
|
|
37
|
+
For TypeScript definitions in your project, inspect `node_modules/@mariozechner/pi-coding-agent/dist/` and `node_modules/@mariozechner/pi-ai/dist/`.
|
|
38
38
|
|
|
39
39
|
## Message Types
|
|
40
40
|
|
package/docs/termux.md
CHANGED
package/docs/tui.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Extensions and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
|
|
6
6
|
|
|
7
|
-
**Source:** [`@
|
|
7
|
+
**Source:** [`@mariozechner/pi-tui`](https://github.com/badlogic/pi-mono/tree/main/packages/tui)
|
|
8
8
|
|
|
9
9
|
## Component Interface
|
|
10
10
|
|
|
@@ -33,7 +33,7 @@ The TUI appends a full SGR reset and OSC 8 reset at the end of each rendered lin
|
|
|
33
33
|
Components that display a text cursor and need IME (Input Method Editor) support should implement the `Focusable` interface:
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
import { CURSOR_MARKER, type Component, type Focusable } from "@
|
|
36
|
+
import { CURSOR_MARKER, type Component, type Focusable } from "@mariozechner/pi-tui";
|
|
37
37
|
|
|
38
38
|
class MyInput implements Component, Focusable {
|
|
39
39
|
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
|
|
|
59
59
|
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.
|
|
60
60
|
|
|
61
61
|
```typescript
|
|
62
|
-
import { Container, type Focusable, Input } from "@
|
|
62
|
+
import { Container, type Focusable, Input } from "@mariozechner/pi-tui";
|
|
63
63
|
|
|
64
64
|
class SearchDialog extends Container implements Focusable {
|
|
65
65
|
private searchInput: Input;
|
|
@@ -179,10 +179,10 @@ See [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for compre
|
|
|
179
179
|
|
|
180
180
|
## Built-in Components
|
|
181
181
|
|
|
182
|
-
Import from `@
|
|
182
|
+
Import from `@mariozechner/pi-tui`:
|
|
183
183
|
|
|
184
184
|
```typescript
|
|
185
|
-
import { Text, Box, Container, Spacer, Markdown } from "@
|
|
185
|
+
import { Text, Box, Container, Spacer, Markdown } from "@mariozechner/pi-tui";
|
|
186
186
|
```
|
|
187
187
|
|
|
188
188
|
### Text
|
|
@@ -264,7 +264,7 @@ const image = new Image(
|
|
|
264
264
|
Use `matchesKey()` for key detection:
|
|
265
265
|
|
|
266
266
|
```typescript
|
|
267
|
-
import { matchesKey, Key } from "@
|
|
267
|
+
import { matchesKey, Key } from "@mariozechner/pi-tui";
|
|
268
268
|
|
|
269
269
|
handleInput(data: string) {
|
|
270
270
|
if (matchesKey(data, Key.up)) {
|
|
@@ -290,7 +290,7 @@ handleInput(data: string) {
|
|
|
290
290
|
**Critical:** Each line from `render()` must not exceed the `width` parameter.
|
|
291
291
|
|
|
292
292
|
```typescript
|
|
293
|
-
import { visibleWidth, truncateToWidth } from "@
|
|
293
|
+
import { visibleWidth, truncateToWidth } from "@mariozechner/pi-tui";
|
|
294
294
|
|
|
295
295
|
render(width: number): string[] {
|
|
296
296
|
// Truncate long lines
|
|
@@ -311,7 +311,7 @@ Example: Interactive selector
|
|
|
311
311
|
import {
|
|
312
312
|
matchesKey, Key,
|
|
313
313
|
truncateToWidth, visibleWidth
|
|
314
|
-
} from "@
|
|
314
|
+
} from "@mariozechner/pi-tui";
|
|
315
315
|
|
|
316
316
|
class MySelector {
|
|
317
317
|
private items: string[];
|
|
@@ -425,8 +425,8 @@ renderResult(result, options, theme) {
|
|
|
425
425
|
**For Markdown**, use `getMarkdownTheme()`:
|
|
426
426
|
|
|
427
427
|
```typescript
|
|
428
|
-
import { getMarkdownTheme } from "@
|
|
429
|
-
import { Markdown } from "@
|
|
428
|
+
import { getMarkdownTheme } from "@mariozechner/pi-coding-agent";
|
|
429
|
+
import { Markdown } from "@mariozechner/pi-tui";
|
|
430
430
|
|
|
431
431
|
renderResult(result, options, theme) {
|
|
432
432
|
const mdTheme = getMarkdownTheme();
|
|
@@ -587,12 +587,12 @@ These patterns cover the most common UI needs in extensions. **Copy these patter
|
|
|
587
587
|
|
|
588
588
|
### Pattern 1: Selection Dialog (SelectList)
|
|
589
589
|
|
|
590
|
-
For letting users pick from a list of options. Use `SelectList` from `@
|
|
590
|
+
For letting users pick from a list of options. Use `SelectList` from `@mariozechner/pi-tui` with `DynamicBorder` for framing.
|
|
591
591
|
|
|
592
592
|
```typescript
|
|
593
|
-
import type { ExtensionAPI } from "@
|
|
594
|
-
import { DynamicBorder } from "@
|
|
595
|
-
import { Container, type SelectItem, SelectList, Text } from "@
|
|
593
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
594
|
+
import { DynamicBorder } from "@mariozechner/pi-coding-agent";
|
|
595
|
+
import { Container, type SelectItem, SelectList, Text } from "@mariozechner/pi-tui";
|
|
596
596
|
|
|
597
597
|
pi.registerCommand("pick", {
|
|
598
598
|
handler: async (_args, ctx) => {
|
|
@@ -650,7 +650,7 @@ pi.registerCommand("pick", {
|
|
|
650
650
|
For operations that take time and should be cancellable. `BorderedLoader` shows a spinner and handles escape to cancel.
|
|
651
651
|
|
|
652
652
|
```typescript
|
|
653
|
-
import { BorderedLoader } from "@
|
|
653
|
+
import { BorderedLoader } from "@mariozechner/pi-coding-agent";
|
|
654
654
|
|
|
655
655
|
pi.registerCommand("fetch", {
|
|
656
656
|
handler: async (_args, ctx) => {
|
|
@@ -679,11 +679,11 @@ pi.registerCommand("fetch", {
|
|
|
679
679
|
|
|
680
680
|
### Pattern 3: Settings/Toggles (SettingsList)
|
|
681
681
|
|
|
682
|
-
For toggling multiple settings. Use `SettingsList` from `@
|
|
682
|
+
For toggling multiple settings. Use `SettingsList` from `@mariozechner/pi-tui` with `getSettingsListTheme()`.
|
|
683
683
|
|
|
684
684
|
```typescript
|
|
685
|
-
import { getSettingsListTheme } from "@
|
|
686
|
-
import { Container, type SettingItem, SettingsList, Text } from "@
|
|
685
|
+
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
|
|
686
|
+
import { Container, type SettingItem, SettingsList, Text } from "@mariozechner/pi-tui";
|
|
687
687
|
|
|
688
688
|
pi.registerCommand("settings", {
|
|
689
689
|
handler: async (_args, ctx) => {
|
|
@@ -792,8 +792,8 @@ Token stats available via `ctx.sessionManager.getBranch()` and `ctx.model`.
|
|
|
792
792
|
Replace the main input editor with a custom implementation. Useful for modal editing (vim), different keybindings (emacs), or specialized input handling.
|
|
793
793
|
|
|
794
794
|
```typescript
|
|
795
|
-
import { CustomEditor, type ExtensionAPI } from "@
|
|
796
|
-
import { matchesKey, truncateToWidth } from "@
|
|
795
|
+
import { CustomEditor, type ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
796
|
+
import { matchesKey, truncateToWidth } from "@mariozechner/pi-tui";
|
|
797
797
|
|
|
798
798
|
type Mode = "normal" | "insert";
|
|
799
799
|
|
|
@@ -133,7 +133,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
|
|
|
133
133
|
See [docs/extensions.md](../../docs/extensions.md) for full documentation.
|
|
134
134
|
|
|
135
135
|
```typescript
|
|
136
|
-
import type { ExtensionAPI } from "@
|
|
136
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
137
137
|
import { Type } from "@sinclair/typebox";
|
|
138
138
|
|
|
139
139
|
export default function (pi: ExtensionAPI) {
|
|
@@ -175,7 +175,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
175
175
|
|
|
176
176
|
**Use StringEnum for string parameters** (required for Google API compatibility):
|
|
177
177
|
```typescript
|
|
178
|
-
import { StringEnum } from "@
|
|
178
|
+
import { StringEnum } from "@mariozechner/pi-ai";
|
|
179
179
|
|
|
180
180
|
// Good
|
|
181
181
|
action: StringEnum(["list", "add"] as const)
|
package/examples/sdk/README.md
CHANGED
|
@@ -29,7 +29,7 @@ npx tsx examples/sdk/01-minimal.ts
|
|
|
29
29
|
## Quick Reference
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
|
-
import { getModel } from "@
|
|
32
|
+
import { getModel } from "@mariozechner/pi-ai";
|
|
33
33
|
import {
|
|
34
34
|
AuthStorage,
|
|
35
35
|
createAgentSession,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
codingTools,
|
|
41
41
|
readOnlyTools,
|
|
42
42
|
readTool, bashTool, editTool, writeTool,
|
|
43
|
-
} from "@
|
|
43
|
+
} from "@mariozechner/pi-coding-agent";
|
|
44
44
|
|
|
45
45
|
// Auth and models setup
|
|
46
46
|
const authStorage = AuthStorage.create();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@draht/coding-agent",
|
|
3
|
-
"version": "2026.3.2
|
|
3
|
+
"version": "2026.3.2",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"drahtConfig": {
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@mariozechner/jiti": "^2.6.2",
|
|
48
|
-
"@draht/agent-core": "
|
|
49
|
-
"@draht/ai": "
|
|
50
|
-
"@draht/tui": "
|
|
48
|
+
"@draht/agent-core": "workspace:*",
|
|
49
|
+
"@draht/ai": "workspace:*",
|
|
50
|
+
"@draht/tui": "workspace:*",
|
|
51
51
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
52
52
|
"chalk": "^5.5.0",
|
|
53
53
|
"cli-highlight": "^2.1.11",
|