agent_profile/adapter/
gemini.rs1use std::path::PathBuf;
10
11use super::{
12 Adapter, AdapterEvidence, AdapterMetadata, Capability, CapabilityClaim, CapabilityState,
13 EnvOverride, Mechanism, PathKind, PlanContext, PlannedLaunch, SupportLevel, profile_dir,
14};
15use crate::config::AppRoot;
16use crate::error::Result;
17use crate::name::ProfileName;
18
19const VAR: &str = "GEMINI_CLI_HOME";
20
21static METADATA: AdapterMetadata = AdapterMetadata {
22 id: "gemini",
23 executable: "gemini",
24 mechanism: Mechanism::Env(VAR),
25 support: SupportLevel::Proven,
26 evidence: AdapterEvidence {
27 mechanism_id: "gemini-cli-home-v1",
28 verified_at: "2026-11-09",
29 upstream_version: "0.67.0",
30 source_url: "https://geminicli.com/docs/cli/enterprise/",
31 notes: "the sandbox delta moved config (projects.json) and history/tmp state into \
32 <target>/.gemini while the default location gained nothing; \
33 GEMINI_API_KEY, GOOGLE_API_KEY and GOOGLE_APPLICATION_CREDENTIALS are the \
34 credential bypass variables (binary strings measured)",
35 },
36 capabilities: &[
37 CapabilityClaim {
38 capability: Capability::ConfigIsolation,
39 state: CapabilityState::Supported,
40 basis: "measured: `+ d /home/agent/probe-target/.gemini` and \
41 `+ f /home/agent/probe-target/.gemini/projects.json` — the variable moved the \
42 configuration inside the target, nested one level as the agent creates `.gemini` \
43 itself",
44 },
45 CapabilityClaim {
46 capability: Capability::CredentialIsolation,
47 state: CapabilityState::Unknown,
48 basis: "unmeasured: separating stored credentials requires a vendor session; \
49 GEMINI_API_KEY, GOOGLE_API_KEY and GOOGLE_APPLICATION_CREDENTIALS \
50 (strings measured) are the documented bypass variables, and no \
51 stored-credential observation was made",
52 },
53 CapabilityClaim {
54 capability: Capability::StateIsolation,
55 state: CapabilityState::Supported,
56 basis: "measured: history and tmp state moved as \
57 `+ d /home/agent/probe-target/.gemini/history` and \
58 `+ d /home/agent/probe-target/.gemini/tmp`",
59 },
60 ],
61 env: &[EnvOverride { name: VAR, sensitive: false }],
62 conflicts: &[],
63 credential_env: &["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_APPLICATION_CREDENTIALS"],
64};
65
66#[derive(Debug, Clone, Copy)]
68pub struct Gemini;
69
70impl Adapter for Gemini {
71 fn metadata(&self) -> &'static AdapterMetadata {
72 &METADATA
73 }
74
75 fn paths(&self, root: &AppRoot, profile: &ProfileName) -> Vec<(PathBuf, PathKind)> {
76 vec![(profile_dir(root, profile, METADATA.id), PathKind::Dir)]
79 }
80
81 fn plan(&self, ctx: &PlanContext<'_>) -> Result<PlannedLaunch> {
82 METADATA.mechanism.plan(self, ctx)
83 }
84}