From a146936a1f2b1d1cff7ba388aa719983d47ce84b Mon Sep 17 00:00:00 2001 From: Mattias Petersson Date: Sun, 12 Jul 2026 16:46:44 +0200 Subject: [PATCH] feat(host): add declarative hosts configuration for Antigravity (Agy) --- hosts/agy.ts | 59 ++++++++++++++++++++++++++++++++++++++++ hosts/index.ts | 5 ++-- test/host-config.test.ts | 6 ++-- 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 hosts/agy.ts diff --git a/hosts/agy.ts b/hosts/agy.ts new file mode 100644 index 000000000..b938b3b1a --- /dev/null +++ b/hosts/agy.ts @@ -0,0 +1,59 @@ +import type { HostConfig } from '../scripts/host-config'; + +const agy: HostConfig = { + name: 'agy', + displayName: 'Antigravity', + cliCommand: 'agy', + cliAliases: [], + + globalRoot: '.gemini/config/plugins/gstack/skills', + localSkillRoot: '.gemini/config/plugins/gstack/skills', + hostSubdir: '.gemini/config/plugins/gstack', + usesEnvVars: true, + + frontmatter: { + mode: 'allowlist', + keepFields: [ + 'name', + 'preamble-tier', + 'version', + 'description', + 'allowed-tools', + 'triggers', + 'hooks', + 'gbrain', + ], + descriptionLimit: null, + }, + + generation: { + generateMetadata: false, + skipSkills: ['codex'], + }, + + pathRewrites: [ + { from: '~/.claude/skills/gstack', to: '$GSTACK_ROOT' }, + { from: '.claude/skills/gstack', to: '.gemini/config/plugins/gstack/skills' }, + { from: '.claude/skills', to: '.gemini/config/plugins/gstack' }, + ], + + toolRewrites: {}, + + suppressedResolvers: ['GBRAIN_CONTEXT_LOAD', 'GBRAIN_SAVE_RESULTS'], + + runtimeRoot: { + globalSymlinks: ['bin', 'browse/dist', 'browse/bin', 'gstack-upgrade', 'ETHOS.md'], + globalFiles: { + 'review': ['checklist.md', 'TODOS-format.md'], + }, + }, + + install: { + prefixable: false, + linkingStrategy: 'symlink-generated', + }, + + learningsMode: 'basic', +}; + +export default agy; diff --git a/hosts/index.ts b/hosts/index.ts index cc1c213b5..4cd643ce4 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 agy from './agy'; /** 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, agy]; /** 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, agy }; diff --git a/test/host-config.test.ts b/test/host-config.test.ts index 577057033..ba7fbc41f 100644 --- a/test/host-config.test.ts +++ b/test/host-config.test.ts @@ -22,6 +22,7 @@ import { slate, cursor, openclaw, + agy, } from '../hosts/index'; import { HOST_PATHS } from '../scripts/resolvers/types'; @@ -30,8 +31,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', () => { @@ -53,6 +54,7 @@ describe('hosts/index.ts', () => { expect(slate.name).toBe('slate'); expect(cursor.name).toBe('cursor'); expect(openclaw.name).toBe('openclaw'); + expect(agy.name).toBe('agy'); }); test('getHostConfig returns correct config', () => {