Add drawer for active files in IDE mode (#4682)
Co-authored-by: Shreya <shreyakeshive@google.com>
This commit is contained in:
parent
5d4b02ca85
commit
1d3ad9d075
|
@ -281,6 +281,7 @@ describe('App UI', () => {
|
||||||
it('should display active file when available', async () => {
|
it('should display active file when available', async () => {
|
||||||
vi.mocked(ideContext.getOpenFilesContext).mockReturnValue({
|
vi.mocked(ideContext.getOpenFilesContext).mockReturnValue({
|
||||||
activeFile: '/path/to/my-file.ts',
|
activeFile: '/path/to/my-file.ts',
|
||||||
|
recentOpenFiles: [{ filePath: '/path/to/my-file.ts', content: 'hello' }],
|
||||||
selectedText: 'hello',
|
selectedText: 'hello',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -293,7 +294,7 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Open File (my-file.ts)');
|
expect(lastFrame()).toContain('1 recent file (ctrl+e to view)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not display active file when not available', async () => {
|
it('should not display active file when not available', async () => {
|
||||||
|
@ -316,9 +317,11 @@ describe('App UI', () => {
|
||||||
it('should display active file and other context', async () => {
|
it('should display active file and other context', async () => {
|
||||||
vi.mocked(ideContext.getOpenFilesContext).mockReturnValue({
|
vi.mocked(ideContext.getOpenFilesContext).mockReturnValue({
|
||||||
activeFile: '/path/to/my-file.ts',
|
activeFile: '/path/to/my-file.ts',
|
||||||
|
recentOpenFiles: [{ filePath: '/path/to/my-file.ts', content: 'hello' }],
|
||||||
selectedText: 'hello',
|
selectedText: 'hello',
|
||||||
});
|
});
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(1);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(1);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue(['GEMINI.md']);
|
||||||
|
|
||||||
const { lastFrame, unmount } = render(
|
const { lastFrame, unmount } = render(
|
||||||
<App
|
<App
|
||||||
|
@ -329,11 +332,14 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Open File (my-file.ts) | 1 GEMINI.md File');
|
expect(lastFrame()).toContain(
|
||||||
|
'Using: 1 recent file (ctrl+e to view) | 1 GEMINI.md file',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display default "GEMINI.md" in footer when contextFileName is not set and count is 1', async () => {
|
it('should display default "GEMINI.md" in footer when contextFileName is not set and count is 1', async () => {
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(1);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(1);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue(['GEMINI.md']);
|
||||||
// For this test, ensure showMemoryUsage is false or debugMode is false if it relies on that
|
// For this test, ensure showMemoryUsage is false or debugMode is false if it relies on that
|
||||||
mockConfig.getDebugMode.mockReturnValue(false);
|
mockConfig.getDebugMode.mockReturnValue(false);
|
||||||
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
||||||
|
@ -347,11 +353,15 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve(); // Wait for any async updates
|
await Promise.resolve(); // Wait for any async updates
|
||||||
expect(lastFrame()).toContain('Using: 1 GEMINI.md File');
|
expect(lastFrame()).toContain('Using: 1 GEMINI.md file');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display default "GEMINI.md" with plural when contextFileName is not set and count is > 1', async () => {
|
it('should display default "GEMINI.md" with plural when contextFileName is not set and count is > 1', async () => {
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(2);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(2);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue([
|
||||||
|
'GEMINI.md',
|
||||||
|
'GEMINI.md',
|
||||||
|
]);
|
||||||
mockConfig.getDebugMode.mockReturnValue(false);
|
mockConfig.getDebugMode.mockReturnValue(false);
|
||||||
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
||||||
|
|
||||||
|
@ -364,7 +374,7 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Using: 2 GEMINI.md Files');
|
expect(lastFrame()).toContain('Using: 2 GEMINI.md files');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display custom contextFileName in footer when set and count is 1', async () => {
|
it('should display custom contextFileName in footer when set and count is 1', async () => {
|
||||||
|
@ -372,6 +382,7 @@ describe('App UI', () => {
|
||||||
workspace: { contextFileName: 'AGENTS.md', theme: 'Default' },
|
workspace: { contextFileName: 'AGENTS.md', theme: 'Default' },
|
||||||
});
|
});
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(1);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(1);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue(['AGENTS.md']);
|
||||||
mockConfig.getDebugMode.mockReturnValue(false);
|
mockConfig.getDebugMode.mockReturnValue(false);
|
||||||
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
||||||
|
|
||||||
|
@ -384,7 +395,7 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Using: 1 AGENTS.md File');
|
expect(lastFrame()).toContain('Using: 1 AGENTS.md file');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a generic message when multiple context files with different names are provided', async () => {
|
it('should display a generic message when multiple context files with different names are provided', async () => {
|
||||||
|
@ -395,6 +406,10 @@ describe('App UI', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(2);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(2);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue([
|
||||||
|
'AGENTS.md',
|
||||||
|
'CONTEXT.md',
|
||||||
|
]);
|
||||||
mockConfig.getDebugMode.mockReturnValue(false);
|
mockConfig.getDebugMode.mockReturnValue(false);
|
||||||
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
||||||
|
|
||||||
|
@ -407,7 +422,7 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Using: 2 Context Files');
|
expect(lastFrame()).toContain('Using: 2 context files');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display custom contextFileName with plural when set and count is > 1', async () => {
|
it('should display custom contextFileName with plural when set and count is > 1', async () => {
|
||||||
|
@ -415,6 +430,11 @@ describe('App UI', () => {
|
||||||
workspace: { contextFileName: 'MY_NOTES.TXT', theme: 'Default' },
|
workspace: { contextFileName: 'MY_NOTES.TXT', theme: 'Default' },
|
||||||
});
|
});
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(3);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(3);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue([
|
||||||
|
'MY_NOTES.TXT',
|
||||||
|
'MY_NOTES.TXT',
|
||||||
|
'MY_NOTES.TXT',
|
||||||
|
]);
|
||||||
mockConfig.getDebugMode.mockReturnValue(false);
|
mockConfig.getDebugMode.mockReturnValue(false);
|
||||||
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
||||||
|
|
||||||
|
@ -427,7 +447,7 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Using: 3 MY_NOTES.TXT Files');
|
expect(lastFrame()).toContain('Using: 3 MY_NOTES.TXT files');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not display context file message if count is 0, even if contextFileName is set', async () => {
|
it('should not display context file message if count is 0, even if contextFileName is set', async () => {
|
||||||
|
@ -435,6 +455,7 @@ describe('App UI', () => {
|
||||||
workspace: { contextFileName: 'ANY_FILE.MD', theme: 'Default' },
|
workspace: { contextFileName: 'ANY_FILE.MD', theme: 'Default' },
|
||||||
});
|
});
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(0);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(0);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue([]);
|
||||||
mockConfig.getDebugMode.mockReturnValue(false);
|
mockConfig.getDebugMode.mockReturnValue(false);
|
||||||
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
mockConfig.getShowMemoryUsage.mockReturnValue(false);
|
||||||
|
|
||||||
|
@ -452,6 +473,10 @@ describe('App UI', () => {
|
||||||
|
|
||||||
it('should display GEMINI.md and MCP server count when both are present', async () => {
|
it('should display GEMINI.md and MCP server count when both are present', async () => {
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(2);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(2);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue([
|
||||||
|
'GEMINI.md',
|
||||||
|
'GEMINI.md',
|
||||||
|
]);
|
||||||
mockConfig.getMcpServers.mockReturnValue({
|
mockConfig.getMcpServers.mockReturnValue({
|
||||||
server1: {} as MCPServerConfig,
|
server1: {} as MCPServerConfig,
|
||||||
});
|
});
|
||||||
|
@ -467,11 +492,12 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('1 MCP Server');
|
expect(lastFrame()).toContain('1 MCP server');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display only MCP server count when GEMINI.md count is 0', async () => {
|
it('should display only MCP server count when GEMINI.md count is 0', async () => {
|
||||||
mockConfig.getGeminiMdFileCount.mockReturnValue(0);
|
mockConfig.getGeminiMdFileCount.mockReturnValue(0);
|
||||||
|
mockConfig.getAllGeminiMdFilenames.mockReturnValue([]);
|
||||||
mockConfig.getMcpServers.mockReturnValue({
|
mockConfig.getMcpServers.mockReturnValue({
|
||||||
server1: {} as MCPServerConfig,
|
server1: {} as MCPServerConfig,
|
||||||
server2: {} as MCPServerConfig,
|
server2: {} as MCPServerConfig,
|
||||||
|
@ -488,7 +514,7 @@ describe('App UI', () => {
|
||||||
);
|
);
|
||||||
currentUnmount = unmount;
|
currentUnmount = unmount;
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
expect(lastFrame()).toContain('Using: 2 MCP Servers');
|
expect(lastFrame()).toContain('Using: 2 MCP servers (ctrl+t to view)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display Tips component by default', async () => {
|
it('should display Tips component by default', async () => {
|
||||||
|
|
|
@ -46,6 +46,7 @@ import { registerCleanup } from '../utils/cleanup.js';
|
||||||
import { DetailedMessagesDisplay } from './components/DetailedMessagesDisplay.js';
|
import { DetailedMessagesDisplay } from './components/DetailedMessagesDisplay.js';
|
||||||
import { HistoryItemDisplay } from './components/HistoryItemDisplay.js';
|
import { HistoryItemDisplay } from './components/HistoryItemDisplay.js';
|
||||||
import { ContextSummaryDisplay } from './components/ContextSummaryDisplay.js';
|
import { ContextSummaryDisplay } from './components/ContextSummaryDisplay.js';
|
||||||
|
import { IDEContextDetailDisplay } from './components/IDEContextDetailDisplay.js';
|
||||||
import { useHistory } from './hooks/useHistoryManager.js';
|
import { useHistory } from './hooks/useHistoryManager.js';
|
||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
import {
|
import {
|
||||||
|
@ -148,6 +149,8 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
||||||
const [showErrorDetails, setShowErrorDetails] = useState<boolean>(false);
|
const [showErrorDetails, setShowErrorDetails] = useState<boolean>(false);
|
||||||
const [showToolDescriptions, setShowToolDescriptions] =
|
const [showToolDescriptions, setShowToolDescriptions] =
|
||||||
useState<boolean>(false);
|
useState<boolean>(false);
|
||||||
|
const [showIDEContextDetail, setShowIDEContextDetail] =
|
||||||
|
useState<boolean>(false);
|
||||||
const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
|
const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
|
||||||
const [quittingMessages, setQuittingMessages] = useState<
|
const [quittingMessages, setQuittingMessages] = useState<
|
||||||
HistoryItem[] | null
|
HistoryItem[] | null
|
||||||
|
@ -465,6 +468,8 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
||||||
if (Object.keys(mcpServers || {}).length > 0) {
|
if (Object.keys(mcpServers || {}).length > 0) {
|
||||||
handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
|
handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
|
||||||
}
|
}
|
||||||
|
} else if (key.ctrl && input === 'e' && ideContext) {
|
||||||
|
setShowIDEContextDetail((prev) => !prev);
|
||||||
} else if (key.ctrl && (input === 'c' || input === 'C')) {
|
} else if (key.ctrl && (input === 'c' || input === 'C')) {
|
||||||
handleExit(ctrlCPressedOnce, setCtrlCPressedOnce, ctrlCTimerRef);
|
handleExit(ctrlCPressedOnce, setCtrlCPressedOnce, ctrlCTimerRef);
|
||||||
} else if (key.ctrl && (input === 'd' || input === 'D')) {
|
} else if (key.ctrl && (input === 'd' || input === 'D')) {
|
||||||
|
@ -861,6 +866,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
||||||
}
|
}
|
||||||
elapsedTime={elapsedTime}
|
elapsedTime={elapsedTime}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
marginTop={1}
|
marginTop={1}
|
||||||
display="flex"
|
display="flex"
|
||||||
|
@ -900,7 +906,9 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
|
||||||
{shellModeActive && <ShellModeIndicator />}
|
{shellModeActive && <ShellModeIndicator />}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
{showIDEContextDetail && (
|
||||||
|
<IDEContextDetailDisplay openFiles={openFiles} />
|
||||||
|
)}
|
||||||
{showErrorDetails && (
|
{showErrorDetails && (
|
||||||
<OverflowProvider>
|
<OverflowProvider>
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
|
|
|
@ -8,7 +8,6 @@ import React from 'react';
|
||||||
import { Text } from 'ink';
|
import { Text } from 'ink';
|
||||||
import { Colors } from '../colors.js';
|
import { Colors } from '../colors.js';
|
||||||
import { type OpenFiles, type MCPServerConfig } from '@google/gemini-cli-core';
|
import { type OpenFiles, type MCPServerConfig } from '@google/gemini-cli-core';
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
interface ContextSummaryDisplayProps {
|
interface ContextSummaryDisplayProps {
|
||||||
geminiMdFileCount: number;
|
geminiMdFileCount: number;
|
||||||
|
@ -34,16 +33,17 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||||
geminiMdFileCount === 0 &&
|
geminiMdFileCount === 0 &&
|
||||||
mcpServerCount === 0 &&
|
mcpServerCount === 0 &&
|
||||||
blockedMcpServerCount === 0 &&
|
blockedMcpServerCount === 0 &&
|
||||||
!openFiles?.activeFile
|
(openFiles?.recentOpenFiles?.length ?? 0) === 0
|
||||||
) {
|
) {
|
||||||
return <Text> </Text>; // Render an empty space to reserve height
|
return <Text> </Text>; // Render an empty space to reserve height
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeFileText = (() => {
|
const recentFilesText = (() => {
|
||||||
if (!openFiles?.activeFile) {
|
const count = openFiles?.recentOpenFiles?.length ?? 0;
|
||||||
|
if (count === 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return `Open File (${path.basename(openFiles.activeFile)})`;
|
return `${count} recent file${count > 1 ? 's' : ''} (ctrl+e to view)`;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const geminiMdText = (() => {
|
const geminiMdText = (() => {
|
||||||
|
@ -51,8 +51,8 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
const allNamesTheSame = new Set(contextFileNames).size < 2;
|
const allNamesTheSame = new Set(contextFileNames).size < 2;
|
||||||
const name = allNamesTheSame ? contextFileNames[0] : 'Context';
|
const name = allNamesTheSame ? contextFileNames[0] : 'context';
|
||||||
return `${geminiMdFileCount} ${name} File${
|
return `${geminiMdFileCount} ${name} file${
|
||||||
geminiMdFileCount > 1 ? 's' : ''
|
geminiMdFileCount > 1 ? 's' : ''
|
||||||
}`;
|
}`;
|
||||||
})();
|
})();
|
||||||
|
@ -65,14 +65,14 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||||
const parts = [];
|
const parts = [];
|
||||||
if (mcpServerCount > 0) {
|
if (mcpServerCount > 0) {
|
||||||
parts.push(
|
parts.push(
|
||||||
`${mcpServerCount} MCP Server${mcpServerCount > 1 ? 's' : ''}`,
|
`${mcpServerCount} MCP server${mcpServerCount > 1 ? 's' : ''}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockedMcpServerCount > 0) {
|
if (blockedMcpServerCount > 0) {
|
||||||
let blockedText = `${blockedMcpServerCount} Blocked`;
|
let blockedText = `${blockedMcpServerCount} Blocked`;
|
||||||
if (mcpServerCount === 0) {
|
if (mcpServerCount === 0) {
|
||||||
blockedText += ` MCP Server${blockedMcpServerCount > 1 ? 's' : ''}`;
|
blockedText += ` MCP server${blockedMcpServerCount > 1 ? 's' : ''}`;
|
||||||
}
|
}
|
||||||
parts.push(blockedText);
|
parts.push(blockedText);
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,8 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||||
|
|
||||||
let summaryText = 'Using: ';
|
let summaryText = 'Using: ';
|
||||||
const summaryParts = [];
|
const summaryParts = [];
|
||||||
if (activeFileText) {
|
if (recentFilesText) {
|
||||||
summaryParts.push(activeFileText);
|
summaryParts.push(recentFilesText);
|
||||||
}
|
}
|
||||||
if (geminiMdText) {
|
if (geminiMdText) {
|
||||||
summaryParts.push(geminiMdText);
|
summaryParts.push(geminiMdText);
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2025 Google LLC
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Box, Text } from 'ink';
|
||||||
|
import { type OpenFiles } from '@google/gemini-cli-core';
|
||||||
|
import { Colors } from '../colors.js';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
interface IDEContextDetailDisplayProps {
|
||||||
|
openFiles: OpenFiles | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function IDEContextDetailDisplay({
|
||||||
|
openFiles,
|
||||||
|
}: IDEContextDetailDisplayProps) {
|
||||||
|
if (
|
||||||
|
!openFiles ||
|
||||||
|
!openFiles.recentOpenFiles ||
|
||||||
|
openFiles.recentOpenFiles.length === 0
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const recentFiles = openFiles.recentOpenFiles || [];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
flexDirection="column"
|
||||||
|
marginTop={1}
|
||||||
|
borderStyle="round"
|
||||||
|
borderColor={Colors.AccentCyan}
|
||||||
|
paddingX={1}
|
||||||
|
>
|
||||||
|
<Text color={Colors.AccentCyan} bold>
|
||||||
|
IDE Context (ctrl+e to toggle)
|
||||||
|
</Text>
|
||||||
|
{recentFiles.length > 0 && (
|
||||||
|
<Box flexDirection="column" marginTop={1}>
|
||||||
|
<Text bold>Recent files:</Text>
|
||||||
|
{recentFiles.map((file) => (
|
||||||
|
<Text key={file.filePath}>
|
||||||
|
- {path.basename(file.filePath)}
|
||||||
|
{file.filePath === openFiles.activeFile ? ' (active)' : ''}
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
|
@ -252,8 +252,11 @@ const createMcpServer = () => {
|
||||||
inputSchema: {},
|
inputSchema: {},
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
const activeEditor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
const filePath = activeEditor ? activeEditor.document.uri.fsPath : '';
|
const filePath =
|
||||||
|
editor && editor.document.uri.scheme === 'file'
|
||||||
|
? editor.document.uri.fsPath
|
||||||
|
: '';
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
return {
|
return {
|
||||||
content: [{ type: 'text', text: `Active file: ${filePath}` }],
|
content: [{ type: 'text', text: `Active file: ${filePath}` }],
|
||||||
|
|
Loading…
Reference in New Issue