diff options
| author | user <user@clank> | 2026-07-22 20:14:21 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-12 19:34:35 +0200 |
| commit | ddc576738dee39b1c8cfe475271a47831a3ec540 (patch) | |
| tree | a752d04aad99caaa47b5ff88572b38912451ec58 | |
| parent | Add reload-hotkey.ts: bind a key (F5) to /reload (diff) | |
| download | sl0ppi-ddc576738dee39b1c8cfe475271a47831a3ec540.tar.gz sl0ppi-ddc576738dee39b1c8cfe475271a47831a3ec540.tar.xz sl0ppi-ddc576738dee39b1c8cfe475271a47831a3ec540.zip | |
reload-hotkey: prefill /reload instead of broken sendUserMessage command
The prior approach couldn't work: shortcut ctx has no reload(), and
sendUserMessage() uses prompt({expandPromptTemplates:false}) which skips
slash-command handling, so "/reload-runtime" went to the model as literal
text. No extension API can invoke reload directly. Best available: F5 drops
the built-in /reload into the editor (guarded against clobbering in-progress
text); user presses Enter. Documented the source-confirmed blockers.
| -rw-r--r-- | pi-ext/reload-hotkey.ts | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/pi-ext/reload-hotkey.ts b/pi-ext/reload-hotkey.ts index 2457a70..833710c 100644 --- a/pi-ext/reload-hotkey.ts +++ b/pi-ext/reload-hotkey.ts @@ -1,40 +1,46 @@ /** * Reload Hotkey * - * Binds a key to pi's /reload (reload extensions, skills, prompts, themes, - * context files) so you don't have to type it during rapid extension dev. + * Convenience for rapid extension dev: a key that gets you to pi's built-in + * /reload with minimal typing. * - * Why a command + shortcut instead of a direct handler: - * ctx.reload() lives on ExtensionCommandContext (command handlers only) — it - * can deadlock if called from event/shortcut/tool contexts, and the shortcut - * handler only gets a plain ExtensionContext. So we register a real command - * (/reload-runtime) that owns the reload, and the shortcut just QUEUES that - * command as a follow-up user message. When idle it runs immediately; mid-run - * it reloads once the agent settles. This is pi's blessed reload pattern. + * WHY IT ONLY PREFILLS (can't fully auto-run): + * There is no extension API that can invoke a reload directly. Confirmed in + * pi's source: + * 1. registerShortcut handlers receive a plain ExtensionContext, which has NO + * ctx.reload() — reload lives on ExtensionCommandContext (command handlers + * only, to avoid re-entrancy deadlocks). + * 2. pi.sendUserMessage() delegates to prompt(text, {expandPromptTemplates: + * false}), and prompt() only runs slash-command handling when + * expandPromptTemplates is true. So a shortcut-sent "/reload" is delivered + * to the MODEL as literal text, never executed. (The reload_runtime tool + * snippet in the docs is broken for this reason.) + * 3. The built-in /reload is handled inside the editor's onSubmit callback, + * which is not exposed to extensions, so we can't submit on your behalf. * - * Change RELOAD_KEY below to taste. Valid keys/modifiers: see keybindings.md - * (letters, digits, f1-f12, and ctrl/shift/alt combos, e.g. "ctrl+alt+r"). + * So the best we can do is drop "/reload" into the editor; you press Enter. + * If a future pi exposes a command/reload API for shortcuts, wire it here. + * + * Change RELOAD_KEY below to taste (see keybindings.md for the key format). */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; const RELOAD_KEY = "f5"; +const RELOAD_TEXT = "/reload"; export default function (pi: ExtensionAPI) { - pi.registerCommand("reload-runtime", { - description: "Reload extensions, skills, prompts, themes, and context files", - handler: async (_args, ctx) => { - await ctx.reload(); - return; - }, - }); - pi.registerShortcut(RELOAD_KEY, { - description: "Reload pi runtime (extensions/skills/prompts/themes)", + description: "Prefill /reload (press Enter to reload the pi runtime)", handler: (ctx) => { - // Queue the command; the command handler owns the actual ctx.reload(). - pi.sendUserMessage("/reload-runtime", { deliverAs: "followUp" }); - if (ctx.hasUI) ctx.ui.notify("Reloading pi runtime…", "info"); + if (!ctx.hasUI) return; + const current = ctx.ui.getEditorText?.() ?? ""; + if (current.trim() && current.trim() !== RELOAD_TEXT) { + ctx.ui.notify(`Editor not empty — type ${RELOAD_TEXT} to reload`, "warning"); + return; + } + ctx.ui.setEditorText(RELOAD_TEXT); + ctx.ui.notify("Press Enter to reload the pi runtime", "info"); }, }); } |
