@@ -2,6 +2,12 @@ export type { MenuAction, ParseError } from "./menu.js"
22export { parseMenuSelection } from "./menu.js"
33export { deriveRepoPathParts , deriveRepoSlug , resolveRepoInput } from "./repo.js"
44
5+ export type DockerNetworkMode = "shared" | "project"
6+
7+ export const defaultDockerNetworkMode : DockerNetworkMode = "shared"
8+
9+ export const defaultDockerSharedNetworkName = "docker-git-shared"
10+
511export interface TemplateConfig {
612 readonly containerName : string
713 readonly serviceName : string
@@ -22,6 +28,8 @@ export interface TemplateConfig {
2228 readonly codexAuthPath : string
2329 readonly codexSharedAuthPath : string
2430 readonly codexHome : string
31+ readonly dockerNetworkMode : DockerNetworkMode
32+ readonly dockerSharedNetworkName : string
2533 readonly enableMcpPlaywright : boolean
2634 readonly pnpmVersion : string
2735}
@@ -262,6 +270,36 @@ export type Command =
262270 | StateCommand
263271 | AuthCommand
264272
273+ // CHANGE: validate docker network mode values at the CLI/config boundary
274+ // WHY: keep compose network behavior explicit and type-safe
275+ // QUOTE(ТЗ): "Что бы среды были изолированы?"
276+ // REF: user-request-2026-02-20-networks
277+ // SOURCE: n/a
278+ // FORMAT THEOREM: ∀x: isDockerNetworkMode(x) -> x ∈ {"shared","project"}
279+ // PURITY: CORE
280+ // EFFECT: n/a
281+ // INVARIANT: returns true only for known modes
282+ // COMPLEXITY: O(1)
283+ export const isDockerNetworkMode = ( value : string ) : value is DockerNetworkMode =>
284+ value === "shared" || value === "project"
285+
286+ // CHANGE: derive compose network name from typed template config
287+ // WHY: keep network naming deterministic across template generation and runtime checks
288+ // QUOTE(ТЗ): "Если я хочу уникальную сеть на каждый контейнер?"
289+ // REF: user-request-2026-02-20-networks
290+ // SOURCE: n/a
291+ // FORMAT THEOREM: ∀cfg: resolveComposeNetworkName(cfg) = n -> deterministic(n)
292+ // PURITY: CORE
293+ // EFFECT: n/a
294+ // INVARIANT: shared mode always resolves to dockerSharedNetworkName; project mode to "<service>-net"
295+ // COMPLEXITY: O(1)
296+ export const resolveComposeNetworkName = (
297+ config : Pick < TemplateConfig , "serviceName" | "dockerNetworkMode" | "dockerSharedNetworkName" >
298+ ) : string =>
299+ config . dockerNetworkMode === "shared"
300+ ? config . dockerSharedNetworkName
301+ : `${ config . serviceName } -net`
302+
265303export const defaultTemplateConfig = {
266304 containerName : "dev-ssh" ,
267305 serviceName : "dev" ,
@@ -277,6 +315,8 @@ export const defaultTemplateConfig = {
277315 codexAuthPath : "./.docker-git/.orch/auth/codex" ,
278316 codexSharedAuthPath : "./.docker-git/.orch/auth/codex" ,
279317 codexHome : "/home/dev/.codex" ,
318+ dockerNetworkMode : defaultDockerNetworkMode ,
319+ dockerSharedNetworkName : defaultDockerSharedNetworkName ,
280320 enableMcpPlaywright : false ,
281321 pnpmVersion : "10.27.0"
282322}
0 commit comments