From 5087426af738ab711ef03026b906810d1024a2de Mon Sep 17 00:00:00 2001
From: liqoingyu
Date: Mon, 19 Jan 2026 11:46:48 +0800
Subject: [PATCH] test(cli): cover MCP resource edge cases
---
.../src/ui/hooks/atCommandProcessor.test.ts | 97 +++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/packages/cli/src/ui/hooks/atCommandProcessor.test.ts b/packages/cli/src/ui/hooks/atCommandProcessor.test.ts
index 3b91dd269..9b1f9635a 100644
--- a/packages/cli/src/ui/hooks/atCommandProcessor.test.ts
+++ b/packages/cli/src/ui/hooks/atCommandProcessor.test.ts
@@ -386,6 +386,103 @@ describe('handleAtCommand', () => {
expect(mockAddItem).not.toHaveBeenCalled();
});
+ it('should not expand MCP resources in untrusted folders', async () => {
+ (mockConfig as unknown as { getMcpServers: () => unknown }).getMcpServers =
+ () =>
+ ({
+ github: {},
+ }) as unknown;
+ const configWithTrust = mockConfig as unknown as {
+ isTrustedFolder: () => boolean;
+ };
+ configWithTrust.isTrustedFolder = () => false;
+
+ const readMcpResourceSpy = vi.spyOn(registry, 'readMcpResource');
+
+ const query = 'Show me the data from @github: repos/owner/repo/issues';
+
+ const result = await handleAtCommand({
+ query,
+ config: mockConfig,
+ addItem: mockAddItem,
+ onDebugMessage: mockOnDebugMessage,
+ messageId: 1004,
+ signal: abortController.signal,
+ });
+
+ expect(result).toEqual({
+ processedQuery: null,
+ shouldProceed: false,
+ });
+ expect(readMcpResourceSpy).toHaveBeenCalledWith(
+ 'github',
+ 'github://repos/owner/repo/issues',
+ );
+ expect(mockAddItem).toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: 'tool_group',
+ tools: [
+ expect.objectContaining({
+ status: ToolCallStatus.Error,
+ resultDisplay: expect.stringContaining('untrusted'),
+ }),
+ ],
+ }),
+ 1004,
+ );
+ });
+
+ it('should preserve trailing punctuation after an MCP resource reference', async () => {
+ (mockConfig as unknown as { getMcpServers: () => unknown }).getMcpServers =
+ () =>
+ ({
+ github: {},
+ }) as unknown;
+
+ vi.spyOn(registry, 'readMcpResource').mockResolvedValue({
+ contents: [
+ {
+ uri: 'github://repos/owner/repo/issues',
+ mimeType: 'application/json',
+ text: '{"ok":true}',
+ },
+ ],
+ } as unknown as Awaited>);
+
+ const query = 'Show me the data from @github: repos/owner/repo/issues.';
+
+ const result = await handleAtCommand({
+ query,
+ config: mockConfig,
+ addItem: mockAddItem,
+ onDebugMessage: mockOnDebugMessage,
+ messageId: 1005,
+ signal: abortController.signal,
+ });
+
+ expect(result).toEqual({
+ processedQuery: [
+ { text: 'Show me the data from @github:repos/owner/repo/issues.' },
+ { text: '\n--- Content from referenced MCP resources ---' },
+ { text: '\nContent from @github:repos/owner/repo/issues:\n' },
+ { text: '{"ok":true}' },
+ { text: '\n--- End of MCP resource content ---' },
+ ],
+ shouldProceed: true,
+ });
+ expect(registry.readMcpResource).toHaveBeenCalledWith(
+ 'github',
+ 'github://repos/owner/repo/issues',
+ );
+ expect(mockAddItem).toHaveBeenCalledWith(
+ expect.objectContaining({
+ type: 'tool_group',
+ tools: [expect.objectContaining({ status: ToolCallStatus.Success })],
+ }),
+ 1005,
+ );
+ });
+
it('should handle query with text before and after @command', async () => {
const fileContent = 'Markdown content.';
const filePath = await createTestFile(