Skip to main content

atomr_agents_coding_cli_vendor_antigravity/
lib.rs

1//! Google Antigravity CLI (`agy`) adapter. Successor to the Gemini CLI
2//! adapter; serves non-Gemini models (Claude, etc.) via the model flag.
3
4#![forbid(unsafe_code)]
5
6mod command;
7mod mapper;
8mod parser;
9
10use std::path::Path;
11
12use async_trait::async_trait;
13
14use atomr_agents_coding_cli_core::{
15    CliCommand, CliEventParser, CliRequest, CliVendor, CliVendorKind, ConceptProjection,
16    MapperError,
17};
18
19pub use command::{build_headless, build_interactive, AntigravityConfig};
20pub use mapper::materialize as materialize_antigravity_config;
21pub use parser::AntigravityParser;
22
23#[derive(Debug, Clone, Default)]
24pub struct AntigravityVendor {
25    config: AntigravityConfig,
26}
27
28impl AntigravityVendor {
29    pub fn new() -> Self {
30        Self::default()
31    }
32
33    pub fn with_config(config: AntigravityConfig) -> Self {
34        Self { config }
35    }
36}
37
38impl From<AntigravityConfig> for AntigravityVendor {
39    fn from(config: AntigravityConfig) -> Self {
40        Self { config }
41    }
42}
43
44#[async_trait]
45impl CliVendor for AntigravityVendor {
46    fn kind(&self) -> CliVendorKind {
47        CliVendorKind::Antigravity
48    }
49
50    fn label(&self) -> &str {
51        "Antigravity CLI"
52    }
53
54    fn build_headless_command(&self, req: &CliRequest, workdir: &Path) -> CliCommand {
55        build_headless(req, workdir, &self.config)
56    }
57
58    fn build_interactive_command(&self, req: &CliRequest, workdir: &Path) -> CliCommand {
59        build_interactive(req, workdir, &self.config)
60    }
61
62    fn new_parser(&self) -> Box<dyn CliEventParser> {
63        Box::new(AntigravityParser::new())
64    }
65
66    async fn materialize_config(
67        &self,
68        projection: &ConceptProjection,
69        workdir: &Path,
70    ) -> Result<(), MapperError> {
71        materialize_antigravity_config(projection, workdir, &self.config).await
72    }
73
74    async fn is_available(&self) -> bool {
75        tokio::process::Command::new("which")
76            .arg(&self.config.binary)
77            .output()
78            .await
79            .map(|o| o.status.success())
80            .unwrap_or(false)
81    }
82}