aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-22 20:14:21 +0200
committeruser <user@clank>2026-08-12 19:34:35 +0200
commitddc576738dee39b1c8cfe475271a47831a3ec540 (patch)
treea752d04aad99caaa47b5ff88572b38912451ec58
parentAdd reload-hotkey.ts: bind a key (F5) to /reload (diff)
downloadsl0ppi-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.ts52
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");
},
});
}