fix: only deactivate on a standalone "stop ponytail" / "normal mode" (#162)

The deactivation check matched the phrase anywhere in the prompt, so an
ordinary request like "add a normal mode toggle" silently turned ponytail
off for the rest of the session. Match the whole message instead (trimmed,
case-insensitive, trailing punctuation ignored) through a shared helper used
by both the Claude/Codex hook and the pi extension.

Fixes #161
This commit is contained in:
Lakshya77089
2026-06-18 22:50:03 +02:00
committed by GitHub
parent 955fff537c
commit 53fd1e850e
5 changed files with 43 additions and 3 deletions
+2 -1
View File
@@ -7,6 +7,7 @@ const {
normalizeMode,
normalizeConfigMode,
normalizePersistedMode,
isDeactivationCommand,
writeDefaultMode,
} = require("../hooks/ponytail-config.js");
const { getPonytailInstructions, filterSkillBodyForMode } = require("../hooks/ponytail-instructions.js");
@@ -133,7 +134,7 @@ export default function ponytailExtension(pi) {
if (event?.source === "extension") return;
const text = String(event?.text || "");
if (currentMode !== "off" && /\b(stop ponytail|normal mode)\b/i.test(text)) {
if (currentMode !== "off" && isDeactivationCommand(text)) {
setMode("off");
}
});
+12
View File
@@ -121,3 +121,15 @@ test("normal mode disables persistent instructions", async () => withTempConfig(
const disabled = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
assert.equal(disabled, undefined);
}));
test("a request mentioning normal mode stays active", async () => withTempConfig(async () => {
const { commands, events } = createPiHarness();
const ctx = createCommandContext();
await events.get("session_start")({ reason: "startup" }, ctx);
await commands.get("ponytail").handler("ultra", ctx);
await events.get("input")({ text: "add a normal mode toggle next to dark mode", source: "interactive" }, ctx);
const result = await events.get("before_agent_start")({ systemPrompt: "BASE" }, ctx);
assert.match(result.systemPrompt, /PONYTAIL MODE ACTIVE/);
}));