docs(coding-agent): fix obsolete extension UI examples closes #6735

This commit is contained in:
Mario Zechner
2026-07-17 09:35:48 +02:00
parent e5e8726836
commit 58575888f5
4 changed files with 49 additions and 30 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- Fixed obsolete custom UI, custom tool, and custom editor examples in the extension documentation ([#6735](https://github.com/earendil-works/pi/issues/6735)).
## [0.80.10] - 2026-07-16
### New Features
+3 -3
View File
@@ -2708,8 +2708,8 @@ class VimEditor extends CustomEditor {
export default function (pi: ExtensionAPI) {
pi.on("session_start", (_event, ctx) => {
ctx.ui.setEditorComponent((_tui, theme, keybindings) =>
new VimEditor(theme, keybindings)
ctx.ui.setEditorComponent((tui, theme, keybindings) =>
new VimEditor(tui, theme, keybindings)
);
});
}
@@ -2718,7 +2718,7 @@ export default function (pi: ExtensionAPI) {
**Key points:**
- Extend `CustomEditor` (not base `Editor`) to get app keybindings (escape to abort, ctrl+d, model switching)
- Call `super.handleInput(data)` for keys you don't handle
- Factory receives `theme` and `keybindings` from the app
- Factory receives `tui`, `theme`, and `keybindings` from the app
- Use `ctx.ui.getEditorComponent()` before `setEditorComponent()` to wrap the previously configured custom editor
- Pass `undefined` to restore default: `ctx.ui.setEditorComponent(undefined)`
+41 -26
View File
@@ -90,19 +90,32 @@ Without this propagation, typing with an IME (Chinese, Japanese, Korean, etc.) w
```typescript
pi.on("session_start", async (_event, ctx) => {
const handle = ctx.ui.custom(myComponent);
// handle.requestRender() - trigger re-render
// handle.close() - restore normal UI
const result = await ctx.ui.custom<string | null>((tui, theme, keybindings, done) =>
new MyComponent({
theme,
keybindings,
onChange: () => tui.requestRender(),
onSelect: (value) => done(value),
onCancel: () => done(null),
})
);
});
```
**In custom tools** via `pi.ui.custom()`:
**In custom tools** via `ctx.ui.custom()`:
```typescript
async execute(toolCallId, params, onUpdate, ctx, signal) {
const handle = pi.ui.custom(myComponent);
// ...
handle.close();
async execute(toolCallId, params, signal, onUpdate, ctx) {
const result = await ctx.ui.custom<string | null>((tui, theme, keybindings, done) =>
new MyComponent({
theme,
keybindings,
onChange: () => tui.requestRender(),
onSelect: (value) => done(value),
onCancel: () => done(null),
})
);
// Use result...
}
```
@@ -374,24 +387,26 @@ Usage in an extension:
```typescript
pi.registerCommand("pick", {
description: "Pick an item",
handler: async (args, ctx) => {
handler: async (_args, ctx) => {
const items = ["Option A", "Option B", "Option C"];
const selector = new MySelector(items);
let handle: { close: () => void; requestRender: () => void };
await new Promise<void>((resolve) => {
selector.onSelect = (item) => {
ctx.ui.notify(`Selected: ${item}`, "info");
handle.close();
resolve();
const selected = await ctx.ui.custom<string | null>((tui, _theme, _keybindings, done) => {
const selector = new MySelector(items);
selector.onSelect = done;
selector.onCancel = () => done(null);
return {
render: (width) => selector.render(width),
handleInput: (data) => {
selector.handleInput(data);
tui.requestRender();
},
invalidate: () => selector.invalidate(),
};
selector.onCancel = () => {
handle.close();
resolve();
};
handle = ctx.ui.custom(selector);
});
if (selected !== null) {
ctx.ui.notify(`Selected: ${selected}`, "info");
}
}
});
```
@@ -486,7 +501,7 @@ class CachedComponent {
}
```
Call `invalidate()` when state changes, then `handle.requestRender()` to trigger re-render.
Call `invalidate()` when state changes, then use the injected `tui.requestRender()` to trigger re-render.
## Invalidation and Theme Changes
@@ -885,9 +900,9 @@ class VimEditor extends CustomEditor {
export default function (pi: ExtensionAPI) {
pi.on("session_start", (_event, ctx) => {
// Factory receives theme and keybindings from the app
// Factory receives the TUI, theme, and keybindings from the app
ctx.ui.setEditorComponent((tui, theme, keybindings) =>
new VimEditor(theme, keybindings)
new VimEditor(tui, theme, keybindings)
);
});
}
@@ -162,7 +162,7 @@ export default function (pi: ExtensionAPI) {
parameters: Type.Object({
name: Type.String({ description: "Name to greet" }),
}),
async execute(toolCallId, params, onUpdate, ctx, signal) {
async execute(toolCallId, params, signal, onUpdate, ctx) {
return {
content: [{ type: "text", text: `Hello, ${params.name}!` }],
details: {},