docs(coding-agent): fix obsolete extension UI examples closes #6735
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)`
|
||||
|
||||
|
||||
@@ -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: {},
|
||||
|
||||
Reference in New Issue
Block a user