nanstey-pi-command-shortcuts

内容来源:README.md(说明文档) · 原始地址 · 查看安装指南

原始内容

@nanstey/pi-command-shortcuts

Bind keyboard shortcuts to any extension slash command in pi.

pi's built-in keybindings.json only remaps built-in actions — it can't bind a key to an extension command like /voice. This extension does, driven by a small JSON config.

Install

pi install npm:@nanstey/pi-command-shortcuts

Usage

Create ~/.pi/agent/command-shortcuts.json mapping keys to commands:

{
  "ctrl+r": "voice",
  "ctrl+g": { "command": "websearch", "args": "" }
}

Reload with /reload (or restart pi). Press the key to run the command.

Each value is either:

  • a string — the command name (no leading slash). The owning extension is auto-discovered by scanning your installed packages.
  • an object{ "command": "...", "from": "...", "args": "..." }
    • command — command name to run (required).
    • from — package name (@scope/pkg) or module path that registers the command. Skips the scan; faster and unambiguous. Optional.
    • args — default argument string passed to the command. Optional.

Keys use pi's key syntax, e.g. ctrl+r, ctrl+shift+v, alt+enter.

How it works

Extension command handlers are private to pi, and shortcut handlers have no "run command by name" API. So this extension re-runs the owning extension's factory with a Proxy of the real pi that:

  • captures registerCommand() handlers,
  • no-ops the other register* / on() calls so nothing is double-registered,
  • forwards every other method (sendMessage, sendUserMessage, …) to the real pi, so a captured handler behaves exactly like the real command.

The resolved handler is cached per binding and invoked when you press the key. Modules are loaded through pi's own loader, so TypeScript extensions work without a build step.

Notes

  • Context limitation. Shortcut handlers receive an ExtensionContext, not the richer ExtensionCommandContext. Commands that rely on command-only methods (newSession, waitForIdle, fork, …) may not work from a key. This is a pi limitation tracked in pi#4422. Commands that only use ctx.ui and messaging (like /voice) work fine.
  • Conflicts. If a key already drives a built-in action (e.g. ctrl+r is the session-picker rename), pi logs a harmless conflict diagnostic and this binding wins in the editor. Pick a free combo (ctrl+shift+…) to avoid it.
  • Discovery. Prefer from for speed and to avoid importing unrelated extensions during the auto-scan.

License

MIT