mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 07:29:42 +02:00
feat(cli): Antigravity run mode
Adds Antigravity as a sixth CLI backend alongside Claude Code, shell, OpenCode, Codex and Gemini, following the existing pluggable-resolver pattern. - `utils/antigravity-cli-resolver.ts` resolves the CLI, mirroring the other resolvers; `GET /api/antigravity/status` reports availability and path. - `ANTIGRAVITY_*` joins the `ALLOWED_ENV_PREFIXES` allowlist in schemas.ts, so env overrides stay CLI-scoped rather than blanket-forwarded. - Session, tmux-manager, mux-interface and types carry the new mode; secrets are injected via socket-scoped `tmux setenv`, never on the spawn command line, so the mode requires tmux with no direct PTY fallback like the other external CLIs. - Frontend: Run-dropdown entry, agent-type option, `ag` tab badge and toolbar colours. `runAntigravity()` routes remote/docker cases through `POST /api/quick-start` and skips the local status probe for them. Tests: test/antigravity-mode.test.ts, plus run-mode-ui and system-routes coverage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,12 +81,18 @@ vi.mock('../../src/utils/gemini-cli-resolver.js', () => ({
|
||||
resolveGeminiDir: vi.fn(() => null),
|
||||
}));
|
||||
|
||||
vi.mock('../../src/utils/antigravity-cli-resolver.js', () => ({
|
||||
isAntigravityAvailable: vi.fn(() => false),
|
||||
resolveAntigravityDir: vi.fn(() => null),
|
||||
}));
|
||||
|
||||
import fs from 'node:fs/promises';
|
||||
import { existsSync, readdirSync } from 'node:fs';
|
||||
import { subagentWatcher } from '../../src/subagent-watcher.js';
|
||||
import { getLifecycleLog } from '../../src/session-lifecycle-log.js';
|
||||
import { isOpenCodeAvailable, resolveOpenCodeDir } from '../../src/utils/opencode-cli-resolver.js';
|
||||
import { isGeminiAvailable, resolveGeminiDir } from '../../src/utils/gemini-cli-resolver.js';
|
||||
import { isAntigravityAvailable, resolveAntigravityDir } from '../../src/utils/antigravity-cli-resolver.js';
|
||||
|
||||
const mockedReadFile = vi.mocked(fs.readFile);
|
||||
const mockedWriteFile = vi.mocked(fs.writeFile);
|
||||
@@ -98,6 +104,8 @@ const mockedIsOpenCodeAvailable = vi.mocked(isOpenCodeAvailable);
|
||||
const mockedResolveOpenCodeDir = vi.mocked(resolveOpenCodeDir);
|
||||
const mockedIsGeminiAvailable = vi.mocked(isGeminiAvailable);
|
||||
const mockedResolveGeminiDir = vi.mocked(resolveGeminiDir);
|
||||
const mockedIsAntigravityAvailable = vi.mocked(isAntigravityAvailable);
|
||||
const mockedResolveAntigravityDir = vi.mocked(resolveAntigravityDir);
|
||||
|
||||
describe('system-routes', () => {
|
||||
let harness: RouteTestHarness;
|
||||
@@ -805,6 +813,32 @@ describe('system-routes', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ========== GET /api/antigravity/status ==========
|
||||
|
||||
describe('GET /api/antigravity/status', () => {
|
||||
it('returns unavailable when agy is not installed', async () => {
|
||||
mockedIsAntigravityAvailable.mockReturnValue(false);
|
||||
mockedResolveAntigravityDir.mockReturnValue(null);
|
||||
|
||||
const res = await harness.app.inject({ method: 'GET', url: '/api/antigravity/status' });
|
||||
expect(res.statusCode).toBe(200);
|
||||
const body = JSON.parse(res.body);
|
||||
expect(body.available).toBe(false);
|
||||
expect(body.path).toBeNull();
|
||||
});
|
||||
|
||||
it('returns available with path when agy is installed', async () => {
|
||||
mockedIsAntigravityAvailable.mockReturnValue(true);
|
||||
mockedResolveAntigravityDir.mockReturnValue('/home/user/.local/bin');
|
||||
|
||||
const res = await harness.app.inject({ method: 'GET', url: '/api/antigravity/status' });
|
||||
expect(res.statusCode).toBe(200);
|
||||
const body = JSON.parse(res.body);
|
||||
expect(body.available).toBe(true);
|
||||
expect(body.path).toBe('/home/user/.local/bin');
|
||||
});
|
||||
});
|
||||
|
||||
// ========== GET /api/execution/model-config ==========
|
||||
|
||||
describe('GET /api/execution/model-config', () => {
|
||||
|
||||
Reference in New Issue
Block a user