From dc83372f8fb890f37153a825860500e6830dba37 Mon Sep 17 00:00:00 2001 From: David Brailovsky Date: Wed, 30 Sep 2026 15:01:08 +0200 Subject: [PATCH] fix(coding-agent): validate extension command registration Reject extension commands without a non-empty string name or a handler at registration, instead of letting them crash the editor when typing /. fixes #10054 --- packages/coding-agent/CHANGELOG.md | 1 + packages/coding-agent/src/core/extensions/loader.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 22e0d8bdc..68721de9e 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -19,6 +19,7 @@ - Fixed codemode `image()` accepting malformed base64 data or unsupported image types, which persisted an invalid image block that made every later provider request fail with HTTP 400 ([#10215](https://github.com/earendil-works/pi/issues/10215)). - Fixed codemode failing to start its script worker from the standalone Windows executable ([#10204](https://github.com/earendil-works/pi/issues/10204)). - Fixed prompt submission slowing down with session length, because resolving the session's model selection looked up the model catalog once per assistant message ([#10198](https://github.com/earendil-works/pi/issues/10198)). +- Fixed extension commands registered without a string name or handler crashing pi when typing `/`; the extension now fails to load with an error instead ([#10054](https://github.com/earendil-works/pi/issues/10054)). ## [0.99.1] - 2026-09-29 diff --git a/packages/coding-agent/src/core/extensions/loader.ts b/packages/coding-agent/src/core/extensions/loader.ts index d2367f780..82511f913 100644 --- a/packages/coding-agent/src/core/extensions/loader.ts +++ b/packages/coding-agent/src/core/extensions/loader.ts @@ -301,6 +301,14 @@ function createExtensionAPI( registerCommand(name: string, options: Omit): void { assertActive(); + if (typeof name !== "string" || name.length === 0) { + throw new Error( + `Command registered by extension "${extension.path}" must have a non-empty string name. Use pi.registerCommand("name", { description, handler }).`, + ); + } + if (typeof options?.handler !== "function") { + throw new Error(`Command "/${name}" registered by extension "${extension.path}" must define handler().`); + } extension.commands.set(name, { name, sourceInfo: extension.sourceInfo,