diff --git a/src/auto-reply/reply.triggers.trigger-handling.handles-inline-commands-strips-it-before-agent.e2e.test.ts b/src/auto-reply/reply.triggers.trigger-handling.handles-inline-commands-strips-it-before-agent.e2e.test.ts index 418f517b5..f34c29800 100644 --- a/src/auto-reply/reply.triggers.trigger-handling.handles-inline-commands-strips-it-before-agent.e2e.test.ts +++ b/src/auto-reply/reply.triggers.trigger-handling.handles-inline-commands-strips-it-before-agent.e2e.test.ts @@ -160,6 +160,35 @@ describe("trigger handling", () => { expect(text).toBe("ok"); }); }); + it("returns a single reply for envelope-prefixed /help", async () => { + await withTempHome(async (home) => { + const blockReplies: Array<{ text?: string }> = []; + const res = await getReplyFromConfig( + { + Body: "[Signal] T: /help", + RawBody: "/help", + CommandBody: "/help", + From: "+1002", + To: "+2000", + Provider: "signal", + Surface: "signal", + SenderName: "T", + SenderId: "signal:+1002", + CommandAuthorized: true, + }, + { + onBlockReply: async (payload) => { + blockReplies.push(payload); + }, + }, + makeCfg(home), + ); + const text = Array.isArray(res) ? res[0]?.text : res?.text; + expect(blockReplies.length).toBe(0); + expect(text).toContain("Help"); + expect(runEmbeddedPiAgent).not.toHaveBeenCalled(); + }); + }); it("drops /status for unauthorized senders", async () => { await withTempHome(async (home) => { const cfg = { diff --git a/src/auto-reply/reply/get-reply-inline-actions.ts b/src/auto-reply/reply/get-reply-inline-actions.ts index 1ecfb2630..6458f0cfc 100644 --- a/src/auto-reply/reply/get-reply-inline-actions.ts +++ b/src/auto-reply/reply/get-reply-inline-actions.ts @@ -11,6 +11,7 @@ import type { InlineDirectives } from "./directive-handling.js"; import { isDirectiveOnly } from "./directive-handling.js"; import type { createModelSelectionState } from "./model-selection.js"; import { extractInlineSimpleCommand } from "./reply-inline.js"; +import { stripStructuralPrefixes } from "./mentions.js"; import type { TypingController } from "./typing.js"; import { listSkillCommandsForWorkspace, resolveSkillCommandInvocation } from "../skill-commands.js"; import { logVerbose } from "../../globals.js"; @@ -297,7 +298,8 @@ export async function handleInlineActions(params: { skillCommands, }); if (inlineResult.reply) { - if (!inlineCommand.cleaned) { + const cleanedAfterStrip = stripStructuralPrefixes(inlineCommand.cleaned); + if (!cleanedAfterStrip) { typing.cleanup(); return { kind: "reply", reply: inlineResult.reply }; }