mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
Agent Skills: Status Bar Integration for Skill Counts (#15741)
This commit is contained in:
@@ -144,10 +144,16 @@ const createMockConfig = (overrides = {}) => ({
|
||||
getDebugMode: vi.fn(() => false),
|
||||
getAccessibility: vi.fn(() => ({})),
|
||||
getMcpServers: vi.fn(() => ({})),
|
||||
getMcpClientManager: vi.fn().mockImplementation(() => ({
|
||||
getBlockedMcpServers: vi.fn(),
|
||||
getMcpServers: vi.fn(),
|
||||
})),
|
||||
getToolRegistry: () => ({
|
||||
getTool: vi.fn(),
|
||||
}),
|
||||
getSkillManager: () => ({
|
||||
getSkills: () => [],
|
||||
}),
|
||||
getMcpClientManager: () => ({
|
||||
getMcpServers: () => ({}),
|
||||
getBlockedMcpServers: () => [],
|
||||
}),
|
||||
...overrides,
|
||||
});
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ export const Composer = () => {
|
||||
blockedMcpServers={
|
||||
config.getMcpClientManager()?.getBlockedMcpServers() ?? []
|
||||
}
|
||||
skillCount={config.getSkillManager().getSkills().length}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
|
||||
@@ -34,14 +34,16 @@ describe('<ContextSummaryDisplay />', () => {
|
||||
openFiles: [{ path: '/a/b/c', timestamp: Date.now() }],
|
||||
},
|
||||
},
|
||||
skillCount: 1,
|
||||
};
|
||||
|
||||
it('should render on a single line on a wide screen', () => {
|
||||
const { lastFrame, unmount } = renderWithWidth(120, baseProps);
|
||||
const output = lastFrame()!;
|
||||
expect(output).toContain(
|
||||
'Using: 1 open file (ctrl+g to view) | 1 GEMINI.md file | 1 MCP server',
|
||||
'1 open file (ctrl+g to view) | 1 GEMINI.md file | 1 MCP server | 1 skill',
|
||||
);
|
||||
expect(output).not.toContain('Using:');
|
||||
// Check for absence of newlines
|
||||
expect(output.includes('\n')).toBe(false);
|
||||
unmount();
|
||||
@@ -51,10 +53,10 @@ describe('<ContextSummaryDisplay />', () => {
|
||||
const { lastFrame, unmount } = renderWithWidth(60, baseProps);
|
||||
const output = lastFrame()!;
|
||||
const expectedLines = [
|
||||
' Using:',
|
||||
' - 1 open file (ctrl+g to view)',
|
||||
' - 1 GEMINI.md file',
|
||||
' - 1 MCP server',
|
||||
' - 1 open file (ctrl+g to view)',
|
||||
' - 1 GEMINI.md file',
|
||||
' - 1 MCP server',
|
||||
' - 1 skill',
|
||||
];
|
||||
const actualLines = output.split('\n');
|
||||
expect(actualLines).toEqual(expectedLines);
|
||||
@@ -86,9 +88,10 @@ describe('<ContextSummaryDisplay />', () => {
|
||||
geminiMdFileCount: 0,
|
||||
contextFileNames: [],
|
||||
mcpServers: {},
|
||||
skillCount: 0,
|
||||
};
|
||||
const { lastFrame, unmount } = renderWithWidth(60, props);
|
||||
const expectedLines = [' Using:', ' - 1 open file (ctrl+g to view)'];
|
||||
const expectedLines = [' - 1 open file (ctrl+g to view)'];
|
||||
const actualLines = lastFrame()!.split('\n');
|
||||
expect(actualLines).toEqual(expectedLines);
|
||||
unmount();
|
||||
|
||||
@@ -17,6 +17,7 @@ interface ContextSummaryDisplayProps {
|
||||
mcpServers?: Record<string, MCPServerConfig>;
|
||||
blockedMcpServers?: Array<{ name: string; extensionName: string }>;
|
||||
ideContext?: IdeContext;
|
||||
skillCount: number;
|
||||
}
|
||||
|
||||
export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||
@@ -25,6 +26,7 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||
mcpServers,
|
||||
blockedMcpServers,
|
||||
ideContext,
|
||||
skillCount,
|
||||
}) => {
|
||||
const { columns: terminalWidth } = useTerminalSize();
|
||||
const isNarrow = isNarrowWidth(terminalWidth);
|
||||
@@ -36,7 +38,8 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||
geminiMdFileCount === 0 &&
|
||||
mcpServerCount === 0 &&
|
||||
blockedMcpServerCount === 0 &&
|
||||
openFileCount === 0
|
||||
openFileCount === 0 &&
|
||||
skillCount === 0
|
||||
) {
|
||||
return <Text> </Text>; // Render an empty space to reserve height
|
||||
}
|
||||
@@ -83,15 +86,23 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||
return parts.join(', ');
|
||||
})();
|
||||
|
||||
const summaryParts = [openFilesText, geminiMdText, mcpText].filter(Boolean);
|
||||
const skillText = (() => {
|
||||
if (skillCount === 0) {
|
||||
return '';
|
||||
}
|
||||
return `${skillCount} skill${skillCount > 1 ? 's' : ''}`;
|
||||
})();
|
||||
|
||||
const summaryParts = [openFilesText, geminiMdText, mcpText, skillText].filter(
|
||||
Boolean,
|
||||
);
|
||||
|
||||
if (isNarrow) {
|
||||
return (
|
||||
<Box flexDirection="column" paddingX={1}>
|
||||
<Text color={theme.text.secondary}>Using:</Text>
|
||||
{summaryParts.map((part, index) => (
|
||||
<Text key={index} color={theme.text.secondary}>
|
||||
{' '}- {part}
|
||||
- {part}
|
||||
</Text>
|
||||
))}
|
||||
</Box>
|
||||
@@ -100,9 +111,7 @@ export const ContextSummaryDisplay: React.FC<ContextSummaryDisplayProps> = ({
|
||||
|
||||
return (
|
||||
<Box paddingX={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
Using: {summaryParts.join(' | ')}
|
||||
</Text>
|
||||
<Text color={theme.text.secondary}>{summaryParts.join(' | ')}</Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user