feat: register Gemini CLI host with dedicated .gemini subdir

Wire the previously-unregistered Gemini CLI HostConfig into the registry.
The rescued config reused Codex's .agents hostSubdir, which collides with
codex under validateAllConfigs (hostSubdir/globalRoot must be unique).
Retarget Gemini to its native .gemini home (matching its GEMINI.md rewrite
and Google's Gemini CLI convention) and bump the host-count assertion 10 -> 11.
This commit is contained in:
fischer33 2026-07-20 17:35:34 +02:00
parent 9417cf0aa0
commit 42055d9fa6
3 changed files with 75 additions and 4 deletions

70
hosts/gemini.ts Normal file
View File

@ -0,0 +1,70 @@
import type { HostConfig } from '../scripts/host-config';
const gemini: HostConfig = {
name: 'gemini',
displayName: 'Gemini CLI',
cliCommand: 'gemini',
cliAliases: ['gemini-cli'],
globalRoot: '.gemini/skills/gstack',
localSkillRoot: '.gemini/skills/gstack',
hostSubdir: '.gemini',
usesEnvVars: true,
frontmatter: {
mode: 'allowlist',
keepFields: ['name', 'description'],
descriptionLimit: null,
},
generation: {
generateMetadata: false,
skipSkills: ['codex'],
},
pathRewrites: [
{ from: '~/.claude/skills/gstack', to: '~/.gemini/skills/gstack' },
{ from: '.claude/skills/gstack', to: '.gemini/skills/gstack' },
{ from: '.claude/skills', to: '.gemini/skills' },
{ from: 'CLAUDE.md', to: 'GEMINI.md' },
],
toolRewrites: {
'use the Bash tool': 'use the run_shell_command tool',
'use the Write tool': 'use the write_file tool',
'use the Read tool': 'use the read_file tool',
'use the Edit tool': 'use the replace_in_file tool',
'use the Agent tool': 'use delegate_to_agent',
'use the Glob tool': 'use the list_directory tool',
'use the Grep tool': 'use the search_files tool',
'the Bash tool': 'the run_shell_command tool',
'the Read tool': 'the read_file tool',
'the Write tool': 'the write_file tool',
'the Edit tool': 'the replace_in_file tool',
},
suppressedResolvers: [
'DESIGN_OUTSIDE_VOICES',
'ADVERSARIAL_STEP',
'CODEX_SECOND_OPINION',
'CODEX_PLAN_REVIEW',
'REVIEW_ARMY',
],
runtimeRoot: {
globalSymlinks: ['bin', 'browse/dist', 'browse/bin', 'gstack-upgrade', 'ETHOS.md'],
globalFiles: {
'review': ['checklist.md', 'TODOS-format.md'],
},
},
install: {
prefixable: false,
linkingStrategy: 'symlink-generated',
},
coAuthorTrailer: 'Co-Authored-By: Gemini CLI <noreply@google.com>',
learningsMode: 'basic',
};
export default gemini;

View File

@ -16,9 +16,10 @@ import cursor from './cursor';
import openclaw from './openclaw';
import hermes from './hermes';
import gbrain from './gbrain';
import gemini from './gemini';
/** All registered host configs. Add new hosts here. */
export const ALL_HOST_CONFIGS: HostConfig[] = [claude, codex, factory, kiro, opencode, slate, cursor, openclaw, hermes, gbrain];
export const ALL_HOST_CONFIGS: HostConfig[] = [claude, codex, factory, kiro, opencode, slate, cursor, openclaw, hermes, gbrain, gemini];
/** Map from host name to config. */
export const HOST_CONFIG_MAP: Record<string, HostConfig> = Object.fromEntries(
@ -65,4 +66,4 @@ export function getExternalHosts(): HostConfig[] {
}
// Re-export individual configs for direct import
export { claude, codex, factory, kiro, opencode, slate, cursor, openclaw, hermes, gbrain };
export { claude, codex, factory, kiro, opencode, slate, cursor, openclaw, hermes, gbrain, gemini };

View File

@ -30,8 +30,8 @@ const ROOT = path.resolve(import.meta.dir, '..');
// ─── hosts/index.ts ─────────────────────────────────────────
describe('hosts/index.ts', () => {
test('ALL_HOST_CONFIGS has 10 hosts', () => {
expect(ALL_HOST_CONFIGS.length).toBe(10);
test('ALL_HOST_CONFIGS has 11 hosts', () => {
expect(ALL_HOST_CONFIGS.length).toBe(11);
});
test('ALL_HOST_NAMES matches config names', () => {