diff --git a/hosts/gemini.ts b/hosts/gemini.ts new file mode 100644 index 000000000..01b02489d --- /dev/null +++ b/hosts/gemini.ts @@ -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 ', + learningsMode: 'basic', +}; + +export default gemini; diff --git a/hosts/index.ts b/hosts/index.ts index cc1c213b5..74a3dc8e4 100644 --- a/hosts/index.ts +++ b/hosts/index.ts @@ -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 = 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 }; diff --git a/test/host-config.test.ts b/test/host-config.test.ts index 577057033..ab0d2cc88 100644 --- a/test/host-config.test.ts +++ b/test/host-config.test.ts @@ -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', () => {