Skip to content

Commit a80a75c

Browse files
committed
refactor(container): extract Android/Playwright MCP helpers to satisfy max-lines lint
Move the Android and Playwright MCP config/sidecar builders into sibling modules so grok.ts, gemini.ts, and docker-compose.ts stay under the 300-line max-lines budget enforced by CI. Pure refactor — rendered output is unchanged (72 container tests still pass). REF: issue-436
1 parent a93d231 commit a80a75c

8 files changed

Lines changed: 263 additions & 233 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// CHANGE: extract the Gemini Android MCP config sync into its own module
2+
// WHY: issue-436 wires mcp-android "the same way" Playwright MCP works; keeping the
3+
// render helper in a dedicated file keeps gemini.ts under the max-lines lint budget
4+
// QUOTE(ТЗ): "Подключить mcp-android так же как работает MCP PLAYRIGHT"
5+
// REF: issue-436
6+
// SOURCE: https://github.com/mobile-next/mobile-mcp
7+
export const renderGeminiMcpAndroidConfig = (): string =>
8+
String.raw`# Gemini CLI: keep Android MCP config in sync with container settings
9+
docker_git_sync_gemini_android_mcp() {
10+
local adb_endpoint="${"$"}{DOCKER_GIT_ANDROID_ADB_ENDPOINT:-}"
11+
GEMINI_CONFIG_SETTINGS_FILE="$GEMINI_CONFIG_SETTINGS_FILE" MCP_ANDROID_ENABLE="${"$"}{MCP_ANDROID_ENABLE:-0}" DOCKER_GIT_ANDROID_ADB_ENDPOINT="$adb_endpoint" node - <<'NODE'
12+
const fs = require("node:fs")
13+
const path = require("node:path")
14+
const settingsPath = process.env.GEMINI_CONFIG_SETTINGS_FILE
15+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
16+
if (typeof settingsPath !== "string" || settingsPath.length === 0) process.exit(0)
17+
18+
let settings = {}
19+
try {
20+
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8"))
21+
if (isRecord(parsed)) settings = parsed
22+
} catch {}
23+
24+
const adbEndpoint = process.env.DOCKER_GIT_ANDROID_ADB_ENDPOINT || ""
25+
const connectPrefix = adbEndpoint.length > 0 ? "adb connect " + adbEndpoint + " >/dev/null 2>&1 || true; " : ""
26+
const nextServers = { ...(isRecord(settings.mcpServers) ? settings.mcpServers : {}) }
27+
if (process.env.MCP_ANDROID_ENABLE === "1") {
28+
nextServers.android = { command: "bash", args: ["-lc", connectPrefix + "exec npx -y @mobilenext/mobile-mcp@latest"], trust: true }
29+
} else {
30+
delete nextServers.android
31+
}
32+
33+
const nextSettings = { ...settings }
34+
Object.keys(nextServers).length > 0 ? nextSettings.mcpServers = nextServers : delete nextSettings.mcpServers
35+
36+
if (JSON.stringify(settings) === JSON.stringify(nextSettings)) process.exit(0)
37+
38+
fs.mkdirSync(path.dirname(settingsPath), { recursive: true })
39+
fs.writeFileSync(settingsPath, JSON.stringify(nextSettings, null, 2) + "\n", { mode: 0o600 })
40+
NODE
41+
}
42+
43+
docker_git_sync_gemini_android_mcp`
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// CHANGE: house the Gemini Playwright MCP config sync in its own module
2+
// WHY: gemini.ts also wires the Android MCP sidecar (issue-436); moving both optional MCP
3+
// config helpers into sibling modules keeps gemini.ts under the max-lines lint budget
4+
// REF: issue-436
5+
export const renderGeminiMcpPlaywrightConfig = (): string =>
6+
String.raw`# Gemini CLI: keep Playwright MCP config in sync with container settings
7+
docker_git_sync_gemini_playwright_mcp() {
8+
local browser_project="${"$"}{DOCKER_GIT_PROJECT_CONTAINER_NAME:-}"; [[ -n "$browser_project" ]] || browser_project="$(hostname)"
9+
local browser_network="container:$browser_project"
10+
GEMINI_CONFIG_SETTINGS_FILE="$GEMINI_CONFIG_SETTINGS_FILE" MCP_PLAYWRIGHT_ENABLE="${"$"}{MCP_PLAYWRIGHT_ENABLE:-0}" DOCKER_GIT_BROWSER_PROJECT="$browser_project" DOCKER_GIT_BROWSER_NETWORK="$browser_network" node - <<'NODE'
11+
const fs = require("node:fs")
12+
const path = require("node:path")
13+
const settingsPath = process.env.GEMINI_CONFIG_SETTINGS_FILE
14+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
15+
if (typeof settingsPath !== "string" || settingsPath.length === 0) process.exit(0)
16+
17+
let settings = {}
18+
try {
19+
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8"))
20+
if (isRecord(parsed)) settings = parsed
21+
} catch {}
22+
23+
const browserProject = process.env.DOCKER_GIT_BROWSER_PROJECT || ""
24+
const browserArgs = browserProject.length > 0 ? ["--project", browserProject, "--network", process.env.DOCKER_GIT_BROWSER_NETWORK || "container:" + browserProject] : []
25+
const nextServers = { ...(isRecord(settings.mcpServers) ? settings.mcpServers : {}) }
26+
if (process.env.MCP_PLAYWRIGHT_ENABLE === "1") {
27+
nextServers.playwright = { command: "browser-connection", args: browserArgs, trust: true }
28+
} else {
29+
delete nextServers.playwright
30+
}
31+
32+
const nextSettings = { ...settings }
33+
Object.keys(nextServers).length > 0 ? nextSettings.mcpServers = nextServers : delete nextSettings.mcpServers
34+
35+
if (JSON.stringify(settings) === JSON.stringify(nextSettings)) process.exit(0)
36+
37+
fs.mkdirSync(path.dirname(settingsPath), { recursive: true })
38+
fs.writeFileSync(settingsPath, JSON.stringify(nextSettings, null, 2) + "\n", { mode: 0o600 })
39+
NODE
40+
}
41+
42+
docker_git_sync_gemini_playwright_mcp`

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

Lines changed: 2 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import type { TemplateConfig } from "../domain.js"
2+
import { renderGeminiMcpAndroidConfig } from "./gemini-android-mcp.js"
3+
import { renderGeminiMcpPlaywrightConfig } from "./gemini-playwright-mcp.js"
24

35
// CHANGE: add Gemini CLI entrypoint configuration
46
// WHY: enable Gemini CLI in Docker with automated auth, trust settings and MCP
@@ -199,82 +201,6 @@ if [[ -d /etc/sudoers.d ]]; then
199201
chmod 0440 /etc/sudoers.d/gemini-agent
200202
fi`
201203

202-
const renderGeminiMcpPlaywrightConfig = (): string =>
203-
String.raw`# Gemini CLI: keep Playwright MCP config in sync with container settings
204-
docker_git_sync_gemini_playwright_mcp() {
205-
local browser_project="${"$"}{DOCKER_GIT_PROJECT_CONTAINER_NAME:-}"; [[ -n "$browser_project" ]] || browser_project="$(hostname)"
206-
local browser_network="container:$browser_project"
207-
GEMINI_CONFIG_SETTINGS_FILE="$GEMINI_CONFIG_SETTINGS_FILE" MCP_PLAYWRIGHT_ENABLE="${"$"}{MCP_PLAYWRIGHT_ENABLE:-0}" DOCKER_GIT_BROWSER_PROJECT="$browser_project" DOCKER_GIT_BROWSER_NETWORK="$browser_network" node - <<'NODE'
208-
const fs = require("node:fs")
209-
const path = require("node:path")
210-
const settingsPath = process.env.GEMINI_CONFIG_SETTINGS_FILE
211-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
212-
if (typeof settingsPath !== "string" || settingsPath.length === 0) process.exit(0)
213-
214-
let settings = {}
215-
try {
216-
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8"))
217-
if (isRecord(parsed)) settings = parsed
218-
} catch {}
219-
220-
const browserProject = process.env.DOCKER_GIT_BROWSER_PROJECT || ""
221-
const browserArgs = browserProject.length > 0 ? ["--project", browserProject, "--network", process.env.DOCKER_GIT_BROWSER_NETWORK || "container:" + browserProject] : []
222-
const nextServers = { ...(isRecord(settings.mcpServers) ? settings.mcpServers : {}) }
223-
if (process.env.MCP_PLAYWRIGHT_ENABLE === "1") {
224-
nextServers.playwright = { command: "browser-connection", args: browserArgs, trust: true }
225-
} else {
226-
delete nextServers.playwright
227-
}
228-
229-
const nextSettings = { ...settings }
230-
Object.keys(nextServers).length > 0 ? nextSettings.mcpServers = nextServers : delete nextSettings.mcpServers
231-
232-
if (JSON.stringify(settings) === JSON.stringify(nextSettings)) process.exit(0)
233-
234-
fs.mkdirSync(path.dirname(settingsPath), { recursive: true })
235-
fs.writeFileSync(settingsPath, JSON.stringify(nextSettings, null, 2) + "\n", { mode: 0o600 })
236-
NODE
237-
}
238-
239-
docker_git_sync_gemini_playwright_mcp`
240-
241-
const renderGeminiMcpAndroidConfig = (): string =>
242-
String.raw`# Gemini CLI: keep Android MCP config in sync with container settings
243-
docker_git_sync_gemini_android_mcp() {
244-
local adb_endpoint="${"$"}{DOCKER_GIT_ANDROID_ADB_ENDPOINT:-}"
245-
GEMINI_CONFIG_SETTINGS_FILE="$GEMINI_CONFIG_SETTINGS_FILE" MCP_ANDROID_ENABLE="${"$"}{MCP_ANDROID_ENABLE:-0}" DOCKER_GIT_ANDROID_ADB_ENDPOINT="$adb_endpoint" node - <<'NODE'
246-
const fs = require("node:fs")
247-
const path = require("node:path")
248-
const settingsPath = process.env.GEMINI_CONFIG_SETTINGS_FILE
249-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
250-
if (typeof settingsPath !== "string" || settingsPath.length === 0) process.exit(0)
251-
252-
let settings = {}
253-
try {
254-
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8"))
255-
if (isRecord(parsed)) settings = parsed
256-
} catch {}
257-
258-
const adbEndpoint = process.env.DOCKER_GIT_ANDROID_ADB_ENDPOINT || ""
259-
const connectPrefix = adbEndpoint.length > 0 ? "adb connect " + adbEndpoint + " >/dev/null 2>&1 || true; " : ""
260-
const nextServers = { ...(isRecord(settings.mcpServers) ? settings.mcpServers : {}) }
261-
if (process.env.MCP_ANDROID_ENABLE === "1") {
262-
nextServers.android = { command: "bash", args: ["-lc", connectPrefix + "exec npx -y @mobilenext/mobile-mcp@latest"], trust: true }
263-
} else {
264-
delete nextServers.android
265-
}
266-
267-
const nextSettings = { ...settings }
268-
Object.keys(nextServers).length > 0 ? nextSettings.mcpServers = nextServers : delete nextSettings.mcpServers
269-
270-
if (JSON.stringify(settings) === JSON.stringify(nextSettings)) process.exit(0)
271-
272-
fs.mkdirSync(path.dirname(settingsPath), { recursive: true })
273-
fs.writeFileSync(settingsPath, JSON.stringify(nextSettings, null, 2) + "\n", { mode: 0o600 })
274-
NODE
275-
}
276-
277-
docker_git_sync_gemini_android_mcp`
278204

279205
const renderGeminiProfileSetup = (config: TemplateConfig): string =>
280206
String.raw`GEMINI_PROFILE="/etc/profile.d/gemini-config.sh"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// CHANGE: extract the Grok Android MCP config sync into its own module
2+
// WHY: issue-436 wires mcp-android "the same way" Playwright MCP works; keeping the
3+
// render helper in a dedicated file keeps grok.ts under the max-lines lint budget
4+
// QUOTE(ТЗ): "Подключить mcp-android так же как работает MCP PLAYRIGHT"
5+
// REF: issue-436
6+
// SOURCE: https://github.com/mobile-next/mobile-mcp
7+
export const renderGrokMcpAndroidConfig = (): string =>
8+
String.raw`# Grok CLI: keep Android MCP config in sync with container settings
9+
docker_git_sync_grok_android_mcp() {
10+
local adb_endpoint="${"$"}{DOCKER_GIT_ANDROID_ADB_ENDPOINT:-}"
11+
GROK_CONFIG_SETTINGS_FILE="$GROK_CONFIG_SETTINGS_FILE" MCP_ANDROID_ENABLE="${"$"}{MCP_ANDROID_ENABLE:-0}" DOCKER_GIT_ANDROID_ADB_ENDPOINT="$adb_endpoint" node - <<'NODE'
12+
const fs = require("node:fs")
13+
const path = require("node:path")
14+
const settingsPath = process.env.GROK_CONFIG_SETTINGS_FILE
15+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
16+
if (typeof settingsPath !== "string" || settingsPath.length === 0) process.exit(0)
17+
18+
let settings = {}
19+
try {
20+
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8"))
21+
if (isRecord(parsed)) settings = parsed
22+
} catch {}
23+
24+
const adbEndpoint = process.env.DOCKER_GIT_ANDROID_ADB_ENDPOINT || ""
25+
const connectPrefix = adbEndpoint.length > 0 ? "adb connect " + adbEndpoint + " >/dev/null 2>&1 || true; " : ""
26+
const nextServers = { ...(isRecord(settings.mcpServers) ? settings.mcpServers : {}) }
27+
if (process.env.MCP_ANDROID_ENABLE === "1") {
28+
nextServers.android = { command: "bash", args: ["-lc", connectPrefix + "exec npx -y @mobilenext/mobile-mcp@latest"], trust: true }
29+
} else {
30+
delete nextServers.android
31+
}
32+
33+
const nextSettings = { ...settings }
34+
Object.keys(nextServers).length > 0 ? nextSettings.mcpServers = nextServers : delete nextSettings.mcpServers
35+
36+
if (JSON.stringify(settings) === JSON.stringify(nextSettings)) process.exit(0)
37+
38+
fs.mkdirSync(path.dirname(settingsPath), { recursive: true })
39+
fs.writeFileSync(settingsPath, JSON.stringify(nextSettings, null, 2) + "\n", { mode: 0o600 })
40+
NODE
41+
}
42+
43+
docker_git_sync_grok_android_mcp`

packages/container/src/core/templates-entrypoint/grok.ts

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { TemplateConfig } from "../domain.js"
2+
import { renderGrokMcpAndroidConfig } from "./grok-android-mcp.js"
23

34
// CHANGE: add Grok CLI entrypoint configuration
45
// WHY: issue #304 requires Grok auth, Playwright MCP and unrestricted agent permissions
@@ -224,44 +225,6 @@ NODE
224225
225226
docker_git_sync_grok_playwright_mcp`
226227

227-
const renderGrokMcpAndroidConfig = (): string =>
228-
String.raw`# Grok CLI: keep Android MCP config in sync with container settings
229-
docker_git_sync_grok_android_mcp() {
230-
local adb_endpoint="${"$"}{DOCKER_GIT_ANDROID_ADB_ENDPOINT:-}"
231-
GROK_CONFIG_SETTINGS_FILE="$GROK_CONFIG_SETTINGS_FILE" MCP_ANDROID_ENABLE="${"$"}{MCP_ANDROID_ENABLE:-0}" DOCKER_GIT_ANDROID_ADB_ENDPOINT="$adb_endpoint" node - <<'NODE'
232-
const fs = require("node:fs")
233-
const path = require("node:path")
234-
const settingsPath = process.env.GROK_CONFIG_SETTINGS_FILE
235-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value)
236-
if (typeof settingsPath !== "string" || settingsPath.length === 0) process.exit(0)
237-
238-
let settings = {}
239-
try {
240-
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8"))
241-
if (isRecord(parsed)) settings = parsed
242-
} catch {}
243-
244-
const adbEndpoint = process.env.DOCKER_GIT_ANDROID_ADB_ENDPOINT || ""
245-
const connectPrefix = adbEndpoint.length > 0 ? "adb connect " + adbEndpoint + " >/dev/null 2>&1 || true; " : ""
246-
const nextServers = { ...(isRecord(settings.mcpServers) ? settings.mcpServers : {}) }
247-
if (process.env.MCP_ANDROID_ENABLE === "1") {
248-
nextServers.android = { command: "bash", args: ["-lc", connectPrefix + "exec npx -y @mobilenext/mobile-mcp@latest"], trust: true }
249-
} else {
250-
delete nextServers.android
251-
}
252-
253-
const nextSettings = { ...settings }
254-
Object.keys(nextServers).length > 0 ? nextSettings.mcpServers = nextServers : delete nextSettings.mcpServers
255-
256-
if (JSON.stringify(settings) === JSON.stringify(nextSettings)) process.exit(0)
257-
258-
fs.mkdirSync(path.dirname(settingsPath), { recursive: true })
259-
fs.writeFileSync(settingsPath, JSON.stringify(nextSettings, null, 2) + "\n", { mode: 0o600 })
260-
NODE
261-
}
262-
263-
docker_git_sync_grok_android_mcp`
264-
265228
const renderGrokSudoConfig = (config: TemplateConfig): string =>
266229
`# Grok CLI: allow passwordless sudo for agent tasks
267230
# Risk rationale: Grok runs inside an isolated per-project container. The sshUser
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { resolveComposeNetworkName, type TemplateConfig } from "../domain.js"
2+
3+
// CHANGE: render an Android emulator sidecar service mirroring the Playwright MCP wiring
4+
// WHY: issue-436 asks to connect mcp-android "the same way" Playwright MCP works, exposing
5+
// a docker-android emulator as a service reachable over ADB for the mobile-mcp server.
6+
// Extracted into its own module so docker-compose.ts stays under the max-lines budget.
7+
// QUOTE(ТЗ): "Подключить mcp-android так же как работает MCP PLAYRIGHT"
8+
// REF: issue-436
9+
// SOURCE: https://github.com/budtmo/docker-android
10+
// PURITY: CORE
11+
// INVARIANT: only emitted when config.enableMcpAndroid === true; image/ports are env-overridable
12+
export type AndroidFragments = {
13+
readonly maybeAndroidEnv: string
14+
readonly maybeAndroidService: string
15+
readonly maybeAndroidVolume: string
16+
}
17+
18+
const defaultAndroidEmulatorImage = "budtmo/docker-android:emulator_14.0"
19+
20+
export const buildAndroidFragments = (
21+
config: TemplateConfig,
22+
resourceLimitsBlock: string
23+
): AndroidFragments => {
24+
if (config.enableMcpAndroid !== true) {
25+
return {
26+
maybeAndroidEnv: "",
27+
maybeAndroidService: "",
28+
maybeAndroidVolume: ""
29+
}
30+
}
31+
32+
const androidContainerName = `${config.containerName}-android`
33+
const androidVolumeName = `${config.volumeName}-android`
34+
const androidImageRef = `\${DOCKER_GIT_ANDROID_EMULATOR_IMAGE:-${defaultAndroidEmulatorImage}}`
35+
const networkName = resolveComposeNetworkName(config)
36+
37+
const maybeAndroidEnv =
38+
` MCP_ANDROID_ENABLE: "1"\n DOCKER_GIT_ANDROID_CONTAINER_NAME: "${androidContainerName}"\n DOCKER_GIT_ANDROID_ADB_ENDPOINT: "\${DOCKER_GIT_ANDROID_ADB_ENDPOINT:-${androidContainerName}:5555}"\n DOCKER_GIT_ANDROID_EMULATOR_IMAGE: "${androidImageRef}"\n`
39+
40+
const maybeAndroidService = `
41+
${config.serviceName}-android:
42+
image: "${androidImageRef}"
43+
container_name: ${androidContainerName}
44+
privileged: true
45+
environment:
46+
EMULATOR_DEVICE: "\${DOCKER_GIT_ANDROID_DEVICE:-Samsung Galaxy S10}"
47+
WEB_VNC: "\${DOCKER_GIT_ANDROID_WEB_VNC:-true}"
48+
EMULATOR_HEADLESS: "\${DOCKER_GIT_ANDROID_HEADLESS:-true}"
49+
devices:
50+
- /dev/kvm
51+
ports:
52+
- "\${DOCKER_GIT_ANDROID_ADB_BIND_HOST:-127.0.0.1}:\${DOCKER_GIT_ANDROID_ADB_PORT:-5555}:5555"
53+
- "\${DOCKER_GIT_ANDROID_NOVNC_BIND_HOST:-127.0.0.1}:\${DOCKER_GIT_ANDROID_NOVNC_PORT:-6080}:6080"
54+
${resourceLimitsBlock} volumes:
55+
- ${androidVolumeName}:/root/.android
56+
networks:
57+
- ${networkName}
58+
`
59+
60+
return {
61+
maybeAndroidEnv,
62+
maybeAndroidService,
63+
maybeAndroidVolume: ` ${androidVolumeName}:`
64+
}
65+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import type { TemplateConfig } from "../domain.js"
2+
import type { ResolvedComposeResourceLimits } from "../resource-limits.js"
3+
import type { DockerComposeRenderOptions } from "./docker-compose.js"
4+
5+
// CHANGE: house the Playwright MCP sidecar fragment builder in its own module
6+
// WHY: docker-compose.ts hosts the optional Android sidecar (issue-436) too; moving both
7+
// optional-sidecar builders into sibling modules keeps docker-compose.ts under the
8+
// max-lines lint budget while grouping the parallel Playwright/Android wiring together
9+
// REF: issue-436
10+
export type PlaywrightFragments = {
11+
readonly maybeDependsOn: string
12+
readonly maybeDockerSocketMount: string
13+
readonly maybePlaywrightEnv: string
14+
readonly maybeBrowserVolume: string
15+
}
16+
17+
const renderBrowserLimitEnv = (
18+
key: string,
19+
value: number | string | undefined
20+
): string => ` ${key}: "\${${key}:-${value ?? ""}}"\n`
21+
22+
const renderOptionalDockerSocketMount = (
23+
shouldEnableLocalDockerSocket: boolean
24+
): string =>
25+
shouldEnableLocalDockerSocket
26+
? ` - /var/run/docker.sock:/var/run/docker.sock`
27+
: ""
28+
29+
export const buildPlaywrightFragments = (
30+
config: TemplateConfig,
31+
resourceLimits: ResolvedComposeResourceLimits | undefined,
32+
options: DockerComposeRenderOptions
33+
): PlaywrightFragments => {
34+
if (!config.enableMcpPlaywright) {
35+
return {
36+
maybeDependsOn: "",
37+
maybeDockerSocketMount: "",
38+
maybePlaywrightEnv: "",
39+
maybeBrowserVolume: ""
40+
}
41+
}
42+
43+
const browserContainerName = `${config.containerName}-browser`
44+
const browserVolumeName = `${config.volumeName}-browser`
45+
const browserImageName = `${browserContainerName}:docker-git-browser`
46+
47+
return {
48+
maybeDependsOn: "",
49+
maybeDockerSocketMount: renderOptionalDockerSocketMount(
50+
options.enableLocalDockerSocket
51+
),
52+
maybePlaywrightEnv:
53+
` MCP_PLAYWRIGHT_ENABLE: "1"\n DOCKER_GIT_PROJECT_CONTAINER_NAME: "${config.containerName}"\n DOCKER_GIT_BROWSER_CONTAINER_NAME: "${browserContainerName}"\n DOCKER_GIT_BROWSER_IMAGE_NAME: "${browserImageName}"\n DOCKER_GIT_BROWSER_VOLUME_NAME: "${browserVolumeName}"\n${
54+
renderBrowserLimitEnv(
55+
"DOCKER_GIT_BROWSER_CPU_LIMIT",
56+
resourceLimits?.cpuLimit
57+
)
58+
}${renderBrowserLimitEnv("DOCKER_GIT_BROWSER_RAM_LIMIT", resourceLimits?.ramLimit)}`,
59+
maybeBrowserVolume: ` ${browserVolumeName}:`
60+
}
61+
}

0 commit comments

Comments
 (0)