Skip to content

Commit b4e3f82

Browse files
committed
fix(ci): extract gemini settings to constants to fix max-lines-per-function
1 parent 5b76224 commit b4e3f82

3 files changed

Lines changed: 80 additions & 247 deletions

File tree

packages/lib/src/core/templates-entrypoint/gemini.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,7 @@ const renderGeminiAuthConfig = (config: TemplateConfig): string =>
9999
.replaceAll("__GEMINI_AUTH_ROOT__", geminiAuthRootContainerPath(config.sshUser))
100100
.replaceAll("__GEMINI_HOME_DIR__", config.geminiHome)
101101

102-
const renderGeminiPermissionSettingsConfig = (config: TemplateConfig): string =>
103-
String.raw`# Gemini CLI: keep trust settings in sync with docker-git defaults
104-
GEMINI_SETTINGS_DIR="${config.geminiHome}"
105-
GEMINI_TRUST_SETTINGS_FILE="$GEMINI_SETTINGS_DIR/trustedFolders.json"
106-
GEMINI_CONFIG_SETTINGS_FILE="$GEMINI_SETTINGS_DIR/settings.json"
107-
108-
# Wait for symlink to be established by the auth config step
109-
mkdir -p "$GEMINI_SETTINGS_DIR" || true
110-
111-
# Disable folder trust prompt and enable auto-approval in settings.json
112-
if [[ ! -f "$GEMINI_CONFIG_SETTINGS_FILE" ]]; then
113-
cat <<'EOF' > "$GEMINI_CONFIG_SETTINGS_FILE"
114-
{
102+
const geminiSettingsJsonTemplate = `{
115103
"model": {
116104
"name": "gemini-3.1-pro-preview-yolo",
117105
"compressionThreshold": 0.9,
@@ -166,7 +154,21 @@ if [[ ! -f "$GEMINI_CONFIG_SETTINGS_FILE" ]]; then
166154
"trust": true
167155
}
168156
}
169-
}
157+
}`
158+
159+
const renderGeminiPermissionSettingsConfig = (config: TemplateConfig): string =>
160+
String.raw`# Gemini CLI: keep trust settings in sync with docker-git defaults
161+
GEMINI_SETTINGS_DIR="${config.geminiHome}"
162+
GEMINI_TRUST_SETTINGS_FILE="$GEMINI_SETTINGS_DIR/trustedFolders.json"
163+
GEMINI_CONFIG_SETTINGS_FILE="$GEMINI_SETTINGS_DIR/settings.json"
164+
165+
# Wait for symlink to be established by the auth config step
166+
mkdir -p "$GEMINI_SETTINGS_DIR" || true
167+
168+
# Disable folder trust prompt and enable auto-approval in settings.json
169+
if [[ ! -f "$GEMINI_CONFIG_SETTINGS_FILE" ]]; then
170+
cat <<'EOF' > "$GEMINI_CONFIG_SETTINGS_FILE"
171+
${geminiSettingsJsonTemplate}
170172
EOF
171173
fi
172174

packages/lib/src/usecases/auth-gemini-helpers.ts

Lines changed: 58 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -237,72 +237,70 @@ export const prepareGeminiCredentialsDir = (
237237
return credentialsDir
238238
})
239239

240+
export const defaultGeminiSettings = {
241+
model: {
242+
name: "gemini-3.1-pro-preview-yolo",
243+
compressionThreshold: 0.9,
244+
disableLoopDetection: true
245+
},
246+
modelConfigs: {
247+
customAliases: {
248+
"yolo-ultra": {
249+
"modelConfig": {
250+
"model": "gemini-3.1-pro-preview-yolo",
251+
"generateContentConfig": {
252+
"tools": [
253+
{
254+
"googleSearch": {}
255+
},
256+
{
257+
"urlContext": {}
258+
}
259+
]
260+
}
261+
}
262+
}
263+
}
264+
},
265+
general: {
266+
defaultApprovalMode: "auto_edit"
267+
},
268+
tools: {
269+
allowed: [
270+
"run_shell_command",
271+
"write_file",
272+
"googleSearch",
273+
"urlContext"
274+
]
275+
},
276+
sandbox: {
277+
enabled: false
278+
},
279+
security: {
280+
folderTrust: {
281+
enabled: false
282+
},
283+
auth: {
284+
selectedType: "oauth-personal"
285+
},
286+
disableYoloMode: false
287+
},
288+
mcpServers: {
289+
playwright: {
290+
command: "docker-git-playwright-mcp",
291+
args: [],
292+
trust: true
293+
}
294+
}
295+
}
296+
240297
export const writeInitialSettings = (credentialsDir: string, fs: FileSystem.FileSystem) =>
241298
Effect.gen(function*(_) {
242299
const settingsPath = `${credentialsDir}/settings.json`
243300
yield* _(
244301
fs.writeFileString(
245302
settingsPath,
246-
JSON.stringify(
247-
{
248-
model: {
249-
name: "gemini-3.1-pro-preview-yolo",
250-
compressionThreshold: 0.9,
251-
disableLoopDetection: true
252-
},
253-
modelConfigs: {
254-
customAliases: {
255-
"yolo-ultra": {
256-
"modelConfig": {
257-
"model": "gemini-3.1-pro-preview-yolo",
258-
"generateContentConfig": {
259-
"tools": [
260-
{
261-
"googleSearch": {}
262-
},
263-
{
264-
"urlContext": {}
265-
}
266-
]
267-
}
268-
}
269-
}
270-
}
271-
},
272-
general: {
273-
defaultApprovalMode: "auto_edit"
274-
},
275-
tools: {
276-
allowed: [
277-
"run_shell_command",
278-
"write_file",
279-
"googleSearch",
280-
"urlContext"
281-
]
282-
},
283-
sandbox: {
284-
enabled: false
285-
},
286-
security: {
287-
folderTrust: {
288-
enabled: false
289-
},
290-
auth: {
291-
selectedType: "oauth-personal"
292-
},
293-
disableYoloMode: false
294-
},
295-
mcpServers: {
296-
playwright: {
297-
command: "docker-git-playwright-mcp",
298-
args: [],
299-
trust: true
300-
}
301-
}
302-
},
303-
null,
304-
2
305-
) + "\n"
303+
JSON.stringify(defaultGeminiSettings, null, 2) + "\n"
306304
)
307305
)
308306

Lines changed: 6 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import type { PlatformError } from "@effect/platform/Error"
22
import { Effect } from "effect"
3-
import type { AuthGeminiLoginCommand, AuthGeminiLogoutCommand, AuthGeminiStatusCommand } from "../core/domain.js"
3+
import type { AuthGeminiLoginCommand } from "../core/domain.js"
44
import type { AuthError, CommandFailedError } from "../shell/errors.js"
55
import {
6+
defaultGeminiSettings,
67
geminiApiKeyPath,
78
geminiContainerHomeDir,
89
geminiCredentialsPath,
9-
geminiEnvFilePath,
1010
geminiImageName,
1111
type GeminiRuntime,
1212
prepareGeminiCredentialsDir,
13-
resolveGeminiAuthMethod,
1413
withGeminiAuth,
1514
writeInitialSettings
1615
} from "./auth-gemini-helpers.js"
@@ -45,66 +44,7 @@ export const authGeminiLogin = (
4544
yield* _(
4645
fs.writeFileString(
4746
settingsPath,
48-
JSON.stringify(
49-
{
50-
model: {
51-
name: "gemini-3.1-pro-preview-yolo",
52-
compressionThreshold: 0.9,
53-
disableLoopDetection: true
54-
},
55-
modelConfigs: {
56-
customAliases: {
57-
"yolo-ultra": {
58-
"modelConfig": {
59-
"model": "gemini-3.1-pro-preview-yolo",
60-
"generateContentConfig": {
61-
"tools": [
62-
{
63-
"googleSearch": {}
64-
},
65-
{
66-
"urlContext": {}
67-
}
68-
]
69-
}
70-
}
71-
}
72-
}
73-
},
74-
general: {
75-
defaultApprovalMode: "auto_edit"
76-
},
77-
tools: {
78-
allowed: [
79-
"run_shell_command",
80-
"write_file",
81-
"googleSearch",
82-
"urlContext"
83-
]
84-
},
85-
sandbox: {
86-
enabled: false
87-
},
88-
security: {
89-
folderTrust: {
90-
enabled: false
91-
},
92-
auth: {
93-
selectedType: "oauth-personal"
94-
},
95-
disableYoloMode: false
96-
},
97-
mcpServers: {
98-
playwright: {
99-
command: "docker-git-playwright-mcp",
100-
args: [],
101-
trust: true
102-
}
103-
}
104-
},
105-
null,
106-
2
107-
) + "\n"
47+
JSON.stringify(defaultGeminiSettings, null, 2) + "\n"
10848
)
10949
)
11050
})).pipe(
@@ -165,66 +105,7 @@ export const authGeminiLoginOauth = (
165105
yield* _(
166106
fs.writeFileString(
167107
settingsPath,
168-
JSON.stringify(
169-
{
170-
model: {
171-
name: "gemini-3.1-pro-preview-yolo",
172-
compressionThreshold: 0.9,
173-
disableLoopDetection: true
174-
},
175-
modelConfigs: {
176-
customAliases: {
177-
"yolo-ultra": {
178-
"modelConfig": {
179-
"model": "gemini-3.1-pro-preview-yolo",
180-
"generateContentConfig": {
181-
"tools": [
182-
{
183-
"googleSearch": {}
184-
},
185-
{
186-
"urlContext": {}
187-
}
188-
]
189-
}
190-
}
191-
}
192-
}
193-
},
194-
general: {
195-
defaultApprovalMode: "auto_edit"
196-
},
197-
tools: {
198-
allowed: [
199-
"run_shell_command",
200-
"write_file",
201-
"googleSearch",
202-
"urlContext"
203-
]
204-
},
205-
sandbox: {
206-
enabled: false
207-
},
208-
security: {
209-
folderTrust: {
210-
enabled: false
211-
},
212-
auth: {
213-
selectedType: "oauth-personal"
214-
},
215-
disableYoloMode: false
216-
},
217-
mcpServers: {
218-
playwright: {
219-
command: "docker-git-playwright-mcp",
220-
args: [],
221-
trust: true
222-
}
223-
}
224-
},
225-
null,
226-
2
227-
) + "\n"
108+
JSON.stringify(defaultGeminiSettings, null, 2) + "\n"
228109
)
229110
)
230111
}),
@@ -234,53 +115,5 @@ export const authGeminiLoginOauth = (
234115
)
235116
}
236117

237-
// CHANGE: show Gemini CLI auth status for a given label
238-
// WHY: allow verifying API key/OAuth presence without exposing credentials
239-
// QUOTE(ТЗ): "Добавь поддержку gemini CLI"
240-
// REF: issue-146
241-
// SOURCE: https://geminicli.com/docs/get-started/authentication/
242-
// FORMAT THEOREM: forall cmd: authGeminiStatus(cmd) -> connected(cmd, method) | disconnected(cmd)
243-
// PURITY: SHELL
244-
// EFFECT: Effect<void, PlatformError | CommandFailedError, GeminiRuntime>
245-
// INVARIANT: never logs API keys or OAuth tokens
246-
// COMPLEXITY: O(1)
247-
export const authGeminiStatus = (
248-
command: AuthGeminiStatusCommand
249-
): Effect.Effect<void, PlatformError | CommandFailedError, GeminiRuntime> =>
250-
withGeminiAuth(command, ({ accountLabel, accountPath, fs }) =>
251-
Effect.gen(function*(_) {
252-
const authMethod = yield* _(resolveGeminiAuthMethod(fs, accountPath))
253-
if (authMethod === "none") {
254-
yield* _(Effect.log(`Gemini not connected (${accountLabel}).`))
255-
return
256-
}
257-
yield* _(Effect.log(`Gemini connected (${accountLabel}, ${authMethod}).`))
258-
}))
259-
260-
// CHANGE: logout Gemini CLI by clearing API key and OAuth credentials for a label
261-
// WHY: allow revoking Gemini CLI access deterministically
262-
// QUOTE(ТЗ): "Добавь поддержку gemini CLI"
263-
// REF: issue-146
264-
// SOURCE: https://geminicli.com/docs/get-started/authentication/
265-
// FORMAT THEOREM: forall cmd: authGeminiLogout(cmd) -> credentials_cleared(cmd)
266-
// PURITY: SHELL
267-
// EFFECT: Effect<void, PlatformError | CommandFailedError, GeminiRuntime>
268-
// INVARIANT: all credential files (API key and OAuth) are removed from account directory
269-
// COMPLEXITY: O(1)
270-
export const authGeminiLogout = (
271-
command: AuthGeminiLogoutCommand
272-
): Effect.Effect<void, PlatformError | CommandFailedError, GeminiRuntime> =>
273-
Effect.gen(function*(_) {
274-
const accountLabel = normalizeAccountLabel(command.label, "default")
275-
yield* _(
276-
withGeminiAuth(command, ({ accountPath, fs }) =>
277-
Effect.gen(function*(_) {
278-
// Clear API key
279-
yield* _(fs.remove(geminiApiKeyPath(accountPath), { force: true }))
280-
yield* _(fs.remove(geminiEnvFilePath(accountPath), { force: true }))
281-
// Clear OAuth credentials (entire .gemini directory)
282-
yield* _(fs.remove(geminiCredentialsPath(accountPath), { recursive: true, force: true }))
283-
}))
284-
)
285-
yield* _(autoSyncState(`chore(state): auth gemini logout ${accountLabel}`))
286-
}).pipe(Effect.asVoid)
118+
export { authGeminiLogout } from "./auth-gemini-logout.js"
119+
export { authGeminiStatus } from "./auth-gemini-status.js"

0 commit comments

Comments
 (0)