























@@ -290,6 +290,46 @@ describe("resolveMessagingTarget (directory fallback)", () => {
290290expect(mocks.resolveTarget).not.toHaveBeenCalled();
291291});
292292293+it("requires exact directory matches before preserving reserved literal targets", async () => {
294+mocks.getChannelPlugin.mockReturnValue({
295+ ...createChannelTestPluginBase({
296+id: "telegram",
297+label: "Telegram",
298+capabilities: { chatTypes: ["direct", "group", "channel"] },
299+}),
300+directory: {
301+listPeers: mocks.listPeers,
302+listPeersLive: mocks.listPeersLive,
303+listGroups: mocks.listGroups,
304+listGroupsLive: mocks.listGroupsLive,
305+},
306+messaging: {
307+targetResolver: {
308+reservedLiterals: ["current", "self", "this", "me"],
309+hint: "<chatId>",
310+resolveTarget: mocks.resolveTarget,
311+},
312+},
313+});
314+mocks.listGroups.mockResolvedValue([
315+{ kind: "group", id: "memes-room", name: "memes" } satisfies ChannelDirectoryEntry,
316+]);
317+mocks.listGroupsLive.mockResolvedValue([]);
318+319+const result = await resolveMessagingTarget({
320+ cfg,
321+channel: "telegram",
322+input: "me",
323+});
324+325+expect(result.ok).toBe(false);
326+if (!result.ok) {
327+expect(result.error.message).toContain('Reserved target "me"');
328+expect(result.error.message).toContain("Telegram");
329+}
330+expect(mocks.resolveTarget).not.toHaveBeenCalled();
331+});
332+293333it("does not reuse directory cache entries across prepared plugin runtimes", async () => {
294334const firstListGroups = vi
295335.fn()
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。