feat(coding-agent): extension command argument autocomplete

This commit is contained in:
Rafał Krzyważnia 2026-01-16 02:30:55 +01:00 committed by Mario Zechner
parent f900eb591d
commit 35e48ca018
5 changed files with 25 additions and 2 deletions

View file

@ -5,6 +5,7 @@
### Added
- Added bash-style argument slicing for prompt templates ([#770](https://github.com/badlogic/pi-mono/pull/770) by [@airtonix](https://github.com/airtonix))
- Extension commands can provide argument auto-completions via `getArgumentCompletions` in `pi.registerCommand()` ([#775](https://github.com/badlogic/pi-mono/pull/775) by [@ribelo](https://github.com/ribelo))
### Fixed

View file

@ -882,6 +882,25 @@ pi.registerCommand("stats", {
});
```
Optional: add argument auto-completion for `/command ...`:
```typescript
import type { AutocompleteItem } from "@mariozechner/pi-tui";
pi.registerCommand("deploy", {
description: "Deploy to an environment",
getArgumentCompletions: (prefix: string): AutocompleteItem[] | null => {
const envs = ["dev", "staging", "prod"];
const items = envs.map((e) => ({ value: e, label: e }));
const filtered = items.filter((i) => i.value.startsWith(prefix));
return filtered.length > 0 ? filtered : null;
},
handler: async (args, ctx) => {
ctx.ui.notify(`Deploying: ${args}`, "info");
},
});
```
**Examples:** [custom-footer.ts](../examples/extensions/custom-footer.ts), [custom-header.ts](../examples/extensions/custom-header.ts), [handoff.ts](../examples/extensions/handoff.ts), [pirate.ts](../examples/extensions/pirate.ts), [plan-mode/index.ts](../examples/extensions/plan-mode/index.ts), [preset.ts](../examples/extensions/preset.ts), [qna.ts](../examples/extensions/qna.ts), [send-user-message.ts](../examples/extensions/send-user-message.ts), [snake.ts](../examples/extensions/snake.ts), [summarize.ts](../examples/extensions/summarize.ts), [todo.ts](../examples/extensions/todo.ts), [tools.ts](../examples/extensions/tools.ts)
### pi.registerMessageRenderer(customType, renderer)

View file

@ -150,7 +150,7 @@ function createExtensionAPI(
});
},
registerCommand(name: string, options: { description?: string; handler: RegisteredCommand["handler"] }): void {
registerCommand(name: string, options: Omit<RegisteredCommand, "name">): void {
extension.commands.set(name, { name, ...options });
},

View file

@ -16,6 +16,7 @@ import type {
} from "@mariozechner/pi-agent-core";
import type { ImageContent, Model, TextContent, ToolResultMessage } from "@mariozechner/pi-ai";
import type {
AutocompleteItem,
Component,
EditorComponent,
EditorTheme,
@ -655,6 +656,7 @@ export type MessageRenderer<T = unknown> = (
export interface RegisteredCommand {
name: string;
description?: string;
getArgumentCompletions?: (argumentPrefix: string) => AutocompleteItem[] | null;
handler: (args: string, ctx: ExtensionCommandContext) => Promise<void>;
}
@ -714,7 +716,7 @@ export interface ExtensionAPI {
// =========================================================================
/** Register a custom command. */
registerCommand(name: string, options: { description?: string; handler: RegisteredCommand["handler"] }): void;
registerCommand(name: string, options: Omit<RegisteredCommand, "name">): void;
/** Register a keyboard shortcut. */
registerShortcut(

View file

@ -319,6 +319,7 @@ export class InteractiveMode {
(cmd) => ({
name: cmd.name,
description: cmd.description ?? "(extension command)",
getArgumentCompletions: cmd.getArgumentCompletions,
}),
);