mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(coding-agent): pass host keybinding hints to extension renderers (#11630)
Fixes #4748. ## Problem Extensions that import `keyText`/`keyHint` from `@earendil-works/pi-coding-agent` can resolve their own copy of the package (their own `node_modules`, or the bundled `cli.js` vs `dist/index.js`). That copy's keybindings are never set by the host, so it falls back to a manager with only `tui.*` bindings, and `keyHint("app.tools.expand", "to expand")` renders as ` to expand`. ## Change The host passes its own `keyText` and `keyHint` to extension renderers, the same way it passes `theme`: - `ToolRenderContext` (`renderCall`/`renderResult` context): `context.keyHint(...)` - `MessageRenderOptions` and `EntryRenderOptions`: `options.keyHint(...)` All three extend a new exported `KeybindingHints` interface. The docs and the `debug-provider` example now use the injected functions and warn against importing them in renderers. Not done: - Moving the `pi-tui` keybindings singleton to `globalThis`. Per the discussion in #7011, extension-facing state should be host-owned and passed through the extension API instead of shared through process-wide module state. - `ctx.ui.keyText`/`keyHint`. No reported case needs them outside renderers, RPC and print modes never install app keybindings, and adding them to `ExtensionUIContext` would break SDK hosts that implement it. ## Tests - `test/extension-keybinding-hints.test.ts`: tool, message, and entry renderers format a user-overridden `app.tools.expand` binding. - `npm run check` passes.
This commit is contained in:
parent
8bc94b19ff
commit
9376c8d17c
13 changed files with 130 additions and 18 deletions
|
|
@ -2520,6 +2520,7 @@ pi.registerTool({
|
|||
- `toolCallId`, `cwd`, `executionStarted`, `argsComplete`, `isPartial`, `expanded`, `showImages`, `isError`
|
||||
- `durationMs` - how long execution took, from the final result; `undefined` while running
|
||||
- `outputPad` - horizontal padding from the `outputPad` setting; renderers with `renderShell: "self"` apply it themselves
|
||||
- `keyText()`, `keyHint()` - format the user's configured keybindings, see [Keybinding Hints](#keybinding-hints)
|
||||
|
||||
Use `context.state` for cross-slot shared state. Keep slot-local caches on the returned component instance when you want to reuse and mutate the same component across renders.
|
||||
|
||||
|
|
@ -2570,24 +2571,24 @@ If a slot intentionally has no visible content, return an empty `Component` such
|
|||
|
||||
#### Keybinding Hints
|
||||
|
||||
Use `keyHint()` to display keybinding hints that respect the active keybinding configuration:
|
||||
Use `keyHint()` and `keyText()` from the render context to display keybinding hints that respect the user's keybinding configuration:
|
||||
|
||||
```typescript
|
||||
import { keyHint } from "@earendil-works/pi-coding-agent";
|
||||
|
||||
renderResult(result, { expanded }, theme, context) {
|
||||
let text = theme.fg("success", "✓ Done");
|
||||
if (!expanded) {
|
||||
text += ` (${keyHint("app.tools.expand", "to expand")})`;
|
||||
text += ` (${context.keyHint("app.tools.expand", "to expand")})`;
|
||||
}
|
||||
return new Text(text, 0, 0);
|
||||
}
|
||||
```
|
||||
|
||||
Available functions:
|
||||
- `keyHint(keybinding, description)` - Formats a configured keybinding id such as `"app.tools.expand"` or `"tui.select.confirm"`
|
||||
- `keyText(keybinding)` - Returns the raw configured key text for a keybinding id
|
||||
- `rawKeyHint(key, description)` - Format a raw key string
|
||||
The same functions are available as `options.keyHint()`/`options.keyText()` in message and entry renderers:
|
||||
|
||||
- `keyHint(keybinding, description)` - Formats a configured keybinding id such as `"app.tools.expand"` or `"tui.select.confirm"`, followed by the description
|
||||
- `keyText(keybinding)` - Returns the raw configured key text for a keybinding id, or `""` if the id has no keys
|
||||
|
||||
In renderers, use these instead of importing `keyHint()` or `keyText()` from `@earendil-works/pi-coding-agent`. An extension can resolve its own copy of the package, for example from its own `node_modules`, and that copy does not see pi's configured keybindings: `app.*` ids then format as `""`. `rawKeyHint(key, description)` formats a literal key string and is safe to import.
|
||||
|
||||
Use namespaced keybinding ids:
|
||||
- Coding-agent ids use the `app.*` namespace, for example `app.tools.expand`, `app.editor.external`, `app.session.rename`
|
||||
|
|
@ -3144,6 +3145,8 @@ pi.registerMessageRenderer("my-extension", (message, options, theme) => {
|
|||
|
||||
if (expanded && message.details) {
|
||||
text += "\n" + theme.fg("dim", JSON.stringify(message.details, null, 2));
|
||||
} else if (message.details) {
|
||||
text += ` (${options.keyHint("app.tools.expand", "to expand")})`;
|
||||
}
|
||||
|
||||
return new Text(text, outputPad, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue