Merge pull request #452 from aaaaron/feat/gemini-adapter-improvements

feat(adapters/gemini-local): Gemini CLI adapter with auth, skills, and sandbox support
This commit is contained in:
Dotta
2026-03-11 13:43:28 -05:00
committed by GitHub
40 changed files with 2295 additions and 27 deletions

View File

@@ -0,0 +1,64 @@
import type { AdapterConfigFieldsProps } from "../types";
import {
DraftInput,
Field,
ToggleField,
} from "../../components/agent-config-primitives";
import { ChoosePathButton } from "../../components/PathInstructionsModal";
const inputClass =
"w-full rounded-md border border-border px-2.5 py-1.5 bg-transparent outline-none text-sm font-mono placeholder:text-muted-foreground/40";
const instructionsFileHint =
"Absolute path to a markdown file (e.g. AGENTS.md) that defines this agent's behavior. Prepended to the Gemini prompt at runtime.";
export function GeminiLocalConfigFields({
isCreate,
values,
set,
config,
eff,
mark,
}: AdapterConfigFieldsProps) {
return (
<>
<Field label="Agent instructions file" hint={instructionsFileHint}>
<div className="flex items-center gap-2">
<DraftInput
value={
isCreate
? values!.instructionsFilePath ?? ""
: eff(
"adapterConfig",
"instructionsFilePath",
String(config.instructionsFilePath ?? ""),
)
}
onCommit={(v) =>
isCreate
? set!({ instructionsFilePath: v })
: mark("adapterConfig", "instructionsFilePath", v || undefined)
}
immediate
className={inputClass}
placeholder="/absolute/path/to/AGENTS.md"
/>
<ChoosePathButton />
</div>
</Field>
<ToggleField
label="Yolo mode"
hint="Run Gemini with --approval-mode yolo for unattended operation."
checked={
isCreate
? values!.dangerouslyBypassSandbox
: eff("adapterConfig", "yolo", config.yolo === true)
}
onChange={(v) =>
isCreate
? set!({ dangerouslyBypassSandbox: v })
: mark("adapterConfig", "yolo", v)
}
/>
</>
);
}

View File

@@ -0,0 +1,12 @@
import type { UIAdapterModule } from "../types";
import { parseGeminiStdoutLine } from "@paperclipai/adapter-gemini-local/ui";
import { GeminiLocalConfigFields } from "./config-fields";
import { buildGeminiLocalConfig } from "@paperclipai/adapter-gemini-local/ui";
export const geminiLocalUIAdapter: UIAdapterModule = {
type: "gemini_local",
label: "Gemini CLI (local)",
parseStdoutLine: parseGeminiStdoutLine,
ConfigFields: GeminiLocalConfigFields,
buildAdapterConfig: buildGeminiLocalConfig,
};

View File

@@ -2,6 +2,7 @@ import type { UIAdapterModule } from "./types";
import { claudeLocalUIAdapter } from "./claude-local";
import { codexLocalUIAdapter } from "./codex-local";
import { cursorLocalUIAdapter } from "./cursor";
import { geminiLocalUIAdapter } from "./gemini-local";
import { openCodeLocalUIAdapter } from "./opencode-local";
import { piLocalUIAdapter } from "./pi-local";
import { openClawGatewayUIAdapter } from "./openclaw-gateway";
@@ -12,6 +13,7 @@ const adaptersByType = new Map<string, UIAdapterModule>(
[
claudeLocalUIAdapter,
codexLocalUIAdapter,
geminiLocalUIAdapter,
openCodeLocalUIAdapter,
piLocalUIAdapter,
cursorLocalUIAdapter,