
























@@ -319,6 +319,19 @@ describe("registerPluginCommand", () => {
319319error: "Agent prompt guidance must be an array of strings",
320320},
321321},
322+{
323+name: "rejects invalid channel scopes",
324+command: {
325+name: "demo",
326+description: "Demo",
327+channels: ["telegram", " "],
328+handler: async () => ({ text: "ok" }),
329+},
330+expected: {
331+ok: false,
332+error: "Command channel 2 cannot be empty",
333+},
334+},
322335] as const)("$name", ({ command, expected }) => {
323336expect(registerPluginCommand("demo-plugin", command)).toEqual(expected);
324337});
@@ -384,6 +397,31 @@ describe("registerPluginCommand", () => {
384397]);
385398});
386399400+it("scopes plugin command matches and native specs to configured channels", () => {
401+const result = registerVoiceCommandForTest({
402+channels: [" Telegram "],
403+description: "Demo command",
404+});
405+406+expect(result).toEqual({ ok: true });
407+expect(matchPluginCommand("/voice", { channel: "telegram" })).toMatchObject({
408+command: expect.objectContaining({
409+name: "voice",
410+channels: ["telegram"],
411+}),
412+});
413+expect(matchPluginCommand("/voice", { channel: "discord" })).toBeNull();
414+expect(matchPluginCommand("/voice")).toMatchObject({
415+command: expect.objectContaining({ name: "voice" }),
416+});
417+expectProviderCommandSpecCases([
418+{ provider: undefined, expectedNames: ["voice"] },
419+{ provider: "telegram", expectedNames: ["voice"] },
420+{ provider: "discord", expectedNames: [] },
421+]);
422+expect(listProviderPluginCommandSpecs("discord")).toEqual([]);
423+});
424+387425it("allows Slack to resolve provider-native plugin specs without changing shared native gating", () => {
388426const result = registerVoiceCommandForTest({
389427nativeNames: {
@@ -570,6 +608,31 @@ describe("registerPluginCommand", () => {
570608expect(observedOwnerStatus).toBeUndefined();
571609});
572610611+it("skips direct plugin command execution on unsupported channels", async () => {
612+let handlerCalled = false;
613+const handler = async () => {
614+handlerCalled = true;
615+return { text: "ok" };
616+};
617+618+const result = await executePluginCommand({
619+command: {
620+name: "voice",
621+description: "Voice command",
622+channels: ["qqbot"],
623+ handler,
624+pluginId: "demo-plugin",
625+},
626+channel: "discord",
627+isAuthorizedSender: true,
628+commandBody: "/voice",
629+config: {},
630+});
631+632+expect(result).toEqual({ continueAgent: true });
633+expect(handlerCalled).toBe(false);
634+});
635+573636it("does not allow direct reserved command registrations to claim owner status", () => {
574637const result = registerPluginCommand(
575638"codex",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。