diff --git a/packages/core/src/core/prompts.test.ts b/packages/core/src/core/prompts.test.ts index 039453ca12f..424da21b210 100644 --- a/packages/core/src/core/prompts.test.ts +++ b/packages/core/src/core/prompts.test.ts @@ -4,12 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { getCoreSystemPrompt, resolvePathFromEnv } from './prompts.js'; import { isGitRepository } from '../utils/gitUtils.js'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import process from 'node:process'; import type { Config } from '../config/config.js'; import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js'; import { GEMINI_DIR } from '../utils/paths.js'; @@ -52,10 +53,12 @@ vi.mock('../config/models.js', async (importOriginal) => { describe('Core System Prompt (prompts.ts)', () => { let mockConfig: Config; + beforeEach(() => { vi.resetAllMocks(); vi.stubEnv('GEMINI_SYSTEM_MD', undefined); vi.stubEnv('GEMINI_WRITE_SYSTEM_MD', undefined); + vi.spyOn(process, 'platform', 'get').mockReturnValue('linux'); mockConfig = { getToolRegistry: vi.fn().mockReturnValue({ getAllToolNames: vi.fn().mockReturnValue([]), @@ -79,6 +82,30 @@ describe('Core System Prompt (prompts.ts)', () => { } as unknown as Config; }); + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('should use Windows-specific commands when platform is win32', () => { + vi.spyOn(process, 'platform', 'get').mockReturnValue('win32'); + vi.mocked(isGitRepository).mockReturnValue(true); + const prompt = getCoreSystemPrompt(mockConfig); + expect(prompt).toContain("'Select-String'"); + expect(prompt).toContain("'Get-Content -Tail 10'"); + expect(prompt).toContain("'Get-Content -TotalCount 10'"); + expect(prompt).toContain('git status ; git diff HEAD ; git log -n 3'); + }); + + it('should use Linux-specific commands when platform is linux', () => { + vi.spyOn(process, 'platform', 'get').mockReturnValue('linux'); + vi.mocked(isGitRepository).mockReturnValue(true); + const prompt = getCoreSystemPrompt(mockConfig); + expect(prompt).toContain("'grep'"); + expect(prompt).toContain("'tail'"); + expect(prompt).toContain("'head'"); + expect(prompt).toContain('git status && git diff HEAD && git log -n 3'); + }); + it('should include available_skills when provided in config', () => { const skills = [ { diff --git a/packages/core/src/core/prompts.ts b/packages/core/src/core/prompts.ts index 0aec32f155b..d5cd879e6ba 100644 --- a/packages/core/src/core/prompts.ts +++ b/packages/core/src/core/prompts.ts @@ -130,6 +130,12 @@ export function getCoreSystemPrompt( const interactiveMode = config.isInteractive(); + const isWindows = process.platform === 'win32'; + const commandSeparator = isWindows ? ';' : '&&'; + const grepCommand = isWindows ? 'Select-String' : 'grep'; + const tailCommand = isWindows ? 'Get-Content -Tail 10' : 'tail'; + const headCommand = isWindows ? 'Get-Content -TotalCount 10' : 'head'; + const skills = config.getSkillManager().getSkills(); let skillsPrompt = ''; if (skills.length > 0) { @@ -260,7 +266,7 @@ IT IS CRITICAL TO FOLLOW THESE GUIDELINES TO AVOID EXCESSIVE TOKEN CONSUMPTION. - If a command is expected to produce a lot of output, use quiet or silent flags where available and appropriate. - Always consider the trade-off between output verbosity and the need for information. If a command's full output is essential for understanding the result, avoid overly aggressive quieting that might obscure important details. - If a command does not have quiet/silent flags or for commands with potentially long output that may not be useful, redirect stdout and stderr to temp files in the project's temporary directory. For example: 'command > /out.log 2> /err.log'. -- After the command runs, inspect the temp files (e.g. '/out.log' and '/err.log') using commands like 'grep', 'tail', 'head', ... (or platform equivalents). Remove the temp files when done. +- After the command runs, inspect the temp files (e.g. '/out.log' and '/err.log') using commands like '${grepCommand}', '${tailCommand}', '${headCommand}', ... (or platform equivalents). Remove the temp files when done. `; } return ''; @@ -338,7 +344,7 @@ ${(function () { - \`git diff HEAD\` to review all changes (including unstaged changes) to tracked files in work tree since last commit. - \`git diff --staged\` to review only staged changes when a partial commit makes sense or was requested by the user. - \`git log -n 3\` to review recent commit messages and match their style (verbosity, formatting, signature line, etc.) -- Combine shell commands whenever possible to save time/steps, e.g. \`git status && git diff HEAD && git log -n 3\`. +- Combine shell commands whenever possible to save time/steps, e.g. \`git status ${commandSeparator} git diff HEAD ${commandSeparator} git log -n 3\`. - Always propose a draft commit message. Never just ask the user to give you the full commit message. - Prefer commit messages that are clear, concise, and focused more on "why" and less on "what".${ interactiveMode