Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/cli/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,8 @@ the `excludedProjectEnvVars` setting in your `settings.json` file.
- This is useful for development and testing.
- **`GEMINI_SYSTEM_MD`**:
- Overrides the base system prompt with the contents of a Markdown file.
- If set to `1` or `true`, it uses the file at `.gemini/system.md`.
- If set to `1` or `true`, it uses the file at `.gemini/system.md`. If that
file is missing, it falls back to `~/.gemini/system.md`.
- If set to a file path, it uses that file. The path can be absolute or
relative. `~` is supported for the home directory.
- The specified file must exist.
Expand Down
5 changes: 3 additions & 2 deletions docs/cli/system-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ via a `.gemini/.env` file. See
- Use the project default path (`.gemini/system.md`):
- `GEMINI_SYSTEM_MD=true` or `GEMINI_SYSTEM_MD=1`
- The CLI reads `./.gemini/system.md` (relative to your current project
directory).
directory). If it does not exist, it falls back to `~/.gemini/system.md`.

- Use a custom file path:
- `GEMINI_SYSTEM_MD=/absolute/path/to/my-system.md`
Expand Down Expand Up @@ -85,7 +85,8 @@ GEMINI.md focused on high‑level guidance and project specifics.

- Error: `missing system prompt file '…'`
- Ensure the referenced path exists and is readable.
- For `GEMINI_SYSTEM_MD=1|true`, create `./.gemini/system.md` in your project.
- For `GEMINI_SYSTEM_MD=1|true`, create `./.gemini/system.md` in your project
or `~/.gemini/system.md` in your home directory.
- Override not taking effect
- Confirm the variable is loaded (use `.gemini/.env` or export in your shell).
- Paths are resolved from the current working directory; try an absolute path.
Expand Down
3 changes: 2 additions & 1 deletion docs/get-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,8 @@ the `advanced.excludedEnvVars` setting in your `settings.json` file.
- Accepts `true`, `false`, `docker`, `podman`, or a custom command string.
- **`GEMINI_SYSTEM_MD`**:
- Replaces the built‑in system prompt with content from a Markdown file.
- `true`/`1`: Use project default path `./.gemini/system.md`.
- `true`/`1`: Use project default path `./.gemini/system.md`; if missing, fall
back to `~/.gemini/system.md`.
- Any other string: Treat as a path (relative/absolute supported, `~`
expands).
- `false`/`0` or unset: Use the built‑in prompt. See
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/core/prompts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,33 @@ describe('Core System Prompt (prompts.ts)', () => {
},
);

it.each(['1', 'true'])(
'should fall back to home system.md when GEMINI_SYSTEM_MD is "%s" and project file is missing',
(value) => {
const defaultPath = path.resolve(path.join(GEMINI_DIR, 'system.md'));
const homeDir = '/Users/test';
const homePath = path.resolve(
path.join(homeDir, GEMINI_DIR, 'system.md'),
);
vi.stubEnv('GEMINI_SYSTEM_MD', value);
vi.spyOn(os, 'homedir').mockReturnValue(homeDir);
vi.mocked(fs.existsSync).mockImplementation((targetPath) => {
if (targetPath === defaultPath) {
return false;
}
if (targetPath === homePath) {
return true;
}
return false;
});
vi.mocked(fs.readFileSync).mockReturnValue('custom system prompt');

const prompt = getCoreSystemPrompt(mockConfig);
expect(fs.readFileSync).toHaveBeenCalledWith(homePath, 'utf8');
expect(prompt).toBe('custom system prompt');
},
);

it('should read from custom path when GEMINI_SYSTEM_MD provides one, preserving case', () => {
const customPath = path.resolve('/custom/path/SyStEm.Md');
vi.stubEnv('GEMINI_SYSTEM_MD', customPath);
Expand Down
28 changes: 27 additions & 1 deletion packages/core/src/core/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ export function resolvePathFromEnv(envVar?: string): {
};
}

function getGlobalSystemMdPath(): string | null {
try {
return path.join(os.homedir(), GEMINI_DIR, 'system.md');
} catch (error) {
debugLogger.warn(
'Could not resolve home directory for system prompt fallback.',
error,
);
return null;
}
}

export function getCoreSystemPrompt(
config: Config,
userMemory?: string,
Expand All @@ -101,7 +113,21 @@ export function getCoreSystemPrompt(

// require file to exist when override is enabled
if (!fs.existsSync(systemMdPath)) {
throw new Error(`missing system prompt file '${systemMdPath}'`);
if (!systemMdResolution.isSwitch) {
throw new Error(`missing system prompt file '${systemMdPath}'`);
}
const globalSystemMdPath = getGlobalSystemMdPath();
if (!globalSystemMdPath) {
throw new Error(
`missing system prompt file '${systemMdPath}' (failed to resolve home directory)`,
);
}
if (!fs.existsSync(globalSystemMdPath)) {
throw new Error(
`missing system prompt file '${systemMdPath}' (also checked '${globalSystemMdPath}')`,
);
}
systemMdPath = globalSystemMdPath;
}
}

Expand Down