Add /hotkeys command, Ctrl+D exit, markdown table borders

This commit is contained in:
Mario Zechner 2025-12-19 01:19:21 +01:00
parent c1f2541639
commit b2f29613e8
4 changed files with 71 additions and 2 deletions

View file

@ -13,6 +13,14 @@
- Built-in tool details types exported: `BashToolDetails`, `ReadToolDetails`, `GrepToolDetails`, `FindToolDetails`, `LsToolDetails`, `TruncationResult`
- Type guards exported for narrowing: `isBashToolResult`, `isReadToolResult`, `isEditToolResult`, `isWriteToolResult`, `isGrepToolResult`, `isFindToolResult`, `isLsToolResult`
### Added
- **Kitty keyboard protocol support**: Shift+Enter, Alt+Enter, Shift+Tab, Ctrl+D, and all Ctrl+key combinations now work in Ghostty, Kitty, WezTerm, and other modern terminals. ([#225](https://github.com/badlogic/pi-mono/pull/225) by [@kim0](https://github.com/kim0))
- **`/hotkeys` command**: Shows all keyboard shortcuts in a formatted table.
- **Markdown table borders**: Tables now render with proper top and bottom borders.
### Changed
- **Skills standard compliance**: Skills now adhere to the [Agent Skills standard](https://agentskills.io/specification). Validates name (must match parent directory, lowercase, max 64 chars), description (required, max 1024 chars), and frontmatter fields. Warns on violations but remains lenient. Prompt format changed to XML structure. Removed `{baseDir}` placeholder in favor of relative paths. ([#231](https://github.com/badlogic/pi-mono/issues/231))

View file

@ -167,6 +167,7 @@ The agent reads, writes, and edits files, and executes commands via bash.
| `/queue` | Set message queue mode: one-at-a-time (default) or all-at-once |
| `/export [file]` | Export session to self-contained HTML |
| `/session` | Show session info: path, message counts, token usage, cost |
| `/hotkeys` | Show all keyboard shortcuts |
| `/changelog` | Display full version history |
| `/branch` | Create new conversation branch from a previous message |
| `/resume` | Switch to a different session (interactive selector) |
@ -199,8 +200,8 @@ The agent reads, writes, and edits files, and executes commands via bash.
|-----|--------|
| Arrow keys | Move cursor / browse history (Up when empty) |
| Option+Left/Right | Move by word |
| Ctrl+A / Home | Start of line |
| Ctrl+E / End | End of line |
| Ctrl+A / Home / Cmd+Left | Start of line |
| Ctrl+E / End / Cmd+Right | End of line |
**Editing:**
@ -219,6 +220,7 @@ The agent reads, writes, and edits files, and executes commands via bash.
| Tab | Path completion / accept autocomplete |
| Escape | Cancel autocomplete / abort streaming |
| Ctrl+C | Clear editor (first) / exit (second) |
| Ctrl+D | Exit (when editor is empty) |
| Shift+Tab | Cycle thinking level |
| Ctrl+P | Cycle models (scoped by `--models`) |
| Ctrl+O | Toggle tool output expansion |

View file

@ -158,6 +158,7 @@ export class InteractiveMode {
{ name: "copy", description: "Copy last agent message to clipboard" },
{ name: "session", description: "Show session info and stats" },
{ name: "changelog", description: "Show changelog entries" },
{ name: "hotkeys", description: "Show all keyboard shortcuts" },
{ name: "branch", description: "Create a new branch from a previous message" },
{ name: "login", description: "Login with OAuth provider" },
{ name: "logout", description: "Logout from OAuth provider" },
@ -207,6 +208,9 @@ export class InteractiveMode {
theme.fg("dim", "ctrl+c twice") +
theme.fg("muted", " to exit") +
"\n" +
theme.fg("dim", "ctrl+d") +
theme.fg("muted", " to exit (empty)") +
"\n" +
theme.fg("dim", "ctrl+k") +
theme.fg("muted", " to delete line") +
"\n" +
@ -619,6 +623,11 @@ export class InteractiveMode {
this.editor.setText("");
return;
}
if (text === "/hotkeys") {
this.handleHotkeysCommand();
this.editor.setText("");
return;
}
if (text === "/branch") {
this.showUserMessageSelector();
this.editor.setText("");
@ -1636,6 +1645,48 @@ export class InteractiveMode {
this.ui.requestRender();
}
private handleHotkeysCommand(): void {
const hotkeys = `
**Navigation**
| Key | Action |
|-----|--------|
| \`Arrow keys\` | Move cursor / browse history (Up when empty) |
| \`Option+Left/Right\` | Move by word |
| \`Ctrl+A\` / \`Home\` / \`Cmd+Left\` | Start of line |
| \`Ctrl+E\` / \`End\` / \`Cmd+Right\` | End of line |
**Editing**
| Key | Action |
|-----|--------|
| \`Enter\` | Send message |
| \`Shift+Enter\` / \`Alt+Enter\` | New line |
| \`Ctrl+W\` / \`Option+Backspace\` | Delete word backwards |
| \`Ctrl+U\` | Delete to start of line |
| \`Ctrl+K\` | Delete to end of line |
**Other**
| Key | Action |
|-----|--------|
| \`Tab\` | Path completion / accept autocomplete |
| \`Escape\` | Cancel autocomplete / abort streaming |
| \`Ctrl+C\` | Clear editor (first) / exit (second) |
| \`Ctrl+D\` | Exit (when editor is empty) |
| \`Shift+Tab\` | Cycle thinking level |
| \`Ctrl+P\` | Cycle models |
| \`Ctrl+O\` | Toggle tool output expansion |
| \`Ctrl+T\` | Toggle thinking block visibility |
| \`/\` | Slash commands |
| \`!\` | Run bash command |
`;
this.chatContainer.addChild(new Spacer(1));
this.chatContainer.addChild(new DynamicBorder());
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Keyboard Shortcuts")), 1, 0));
this.chatContainer.addChild(new Spacer(1));
this.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 1, getMarkdownTheme()));
this.chatContainer.addChild(new DynamicBorder());
this.ui.requestRender();
}
private async handleClearCommand(): Promise<void> {
// Stop loading animation
if (this.loadingAnimation) {