docs(coding-agent): fix obsolete extension UI examples closes #6735
This commit is contained in:
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## [0.80.10] - 2026-07-16
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
@@ -2708,8 +2708,8 @@ class VimEditor extends CustomEditor {
|
|||||||
|
|
||||||
export default function (pi: ExtensionAPI) {
|
export default function (pi: ExtensionAPI) {
|
||||||
pi.on("session_start", (_event, ctx) => {
|
pi.on("session_start", (_event, ctx) => {
|
||||||
ctx.ui.setEditorComponent((_tui, theme, keybindings) =>
|
ctx.ui.setEditorComponent((tui, theme, keybindings) =>
|
||||||
new VimEditor(theme, keybindings)
|
new VimEditor(tui, theme, keybindings)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2718,7 +2718,7 @@ export default function (pi: ExtensionAPI) {
|
|||||||
**Key points:**
|
**Key points:**
|
||||||
- Extend `CustomEditor` (not base `Editor`) to get app keybindings (escape to abort, ctrl+d, model switching)
|
- 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
|
- 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
|
- Use `ctx.ui.getEditorComponent()` before `setEditorComponent()` to wrap the previously configured custom editor
|
||||||
- Pass `undefined` to restore default: `ctx.ui.setEditorComponent(undefined)`
|
- 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
|
```typescript
|
||||||
pi.on("session_start", async (_event, ctx) => {
|
pi.on("session_start", async (_event, ctx) => {
|
||||||
const handle = ctx.ui.custom(myComponent);
|
const result = await ctx.ui.custom<string | null>((tui, theme, keybindings, done) =>
|
||||||
// handle.requestRender() - trigger re-render
|
new MyComponent({
|
||||||
// handle.close() - restore normal UI
|
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
|
```typescript
|
||||||
async execute(toolCallId, params, onUpdate, ctx, signal) {
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
||||||
const handle = pi.ui.custom(myComponent);
|
const result = await ctx.ui.custom<string | null>((tui, theme, keybindings, done) =>
|
||||||
// ...
|
new MyComponent({
|
||||||
handle.close();
|
theme,
|
||||||
|
keybindings,
|
||||||
|
onChange: () => tui.requestRender(),
|
||||||
|
onSelect: (value) => done(value),
|
||||||
|
onCancel: () => done(null),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// Use result...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -374,24 +387,26 @@ Usage in an extension:
|
|||||||
```typescript
|
```typescript
|
||||||
pi.registerCommand("pick", {
|
pi.registerCommand("pick", {
|
||||||
description: "Pick an item",
|
description: "Pick an item",
|
||||||
handler: async (args, ctx) => {
|
handler: async (_args, ctx) => {
|
||||||
const items = ["Option A", "Option B", "Option C"];
|
const items = ["Option A", "Option B", "Option C"];
|
||||||
const selector = new MySelector(items);
|
const selected = await ctx.ui.custom<string | null>((tui, _theme, _keybindings, done) => {
|
||||||
|
const selector = new MySelector(items);
|
||||||
|
selector.onSelect = done;
|
||||||
|
selector.onCancel = () => done(null);
|
||||||
|
|
||||||
let handle: { close: () => void; requestRender: () => void };
|
return {
|
||||||
|
render: (width) => selector.render(width),
|
||||||
await new Promise<void>((resolve) => {
|
handleInput: (data) => {
|
||||||
selector.onSelect = (item) => {
|
selector.handleInput(data);
|
||||||
ctx.ui.notify(`Selected: ${item}`, "info");
|
tui.requestRender();
|
||||||
handle.close();
|
},
|
||||||
resolve();
|
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
|
## Invalidation and Theme Changes
|
||||||
|
|
||||||
@@ -885,9 +900,9 @@ class VimEditor extends CustomEditor {
|
|||||||
|
|
||||||
export default function (pi: ExtensionAPI) {
|
export default function (pi: ExtensionAPI) {
|
||||||
pi.on("session_start", (_event, ctx) => {
|
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) =>
|
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({
|
parameters: Type.Object({
|
||||||
name: Type.String({ description: "Name to greet" }),
|
name: Type.String({ description: "Name to greet" }),
|
||||||
}),
|
}),
|
||||||
async execute(toolCallId, params, onUpdate, ctx, signal) {
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
||||||
return {
|
return {
|
||||||
content: [{ type: "text", text: `Hello, ${params.name}!` }],
|
content: [{ type: "text", text: `Hello, ${params.name}!` }],
|
||||||
details: {},
|
details: {},
|
||||||
|
|||||||
Reference in New Issue
Block a user