@@ -29,25 +29,39 @@ const filterReserved = (
2929 return path . resolve ( item . projectDir ) !== resolvedExclude
3030}
3131
32- // CHANGE: collect reserved SSH ports from existing docker-git projects
33- // WHY: keep ports stable per project even when containers are stopped
32+ // CHANGE: collect SSH ports currently occupied by existing docker-git projects
33+ // WHY: avoid port collisions while allowing reuse of ports from stopped projects
3434// QUOTE(ТЗ): "для каждого докера брать должен свой порт"
3535// REF: user-request-2026-02-05-port-reserve
3636// SOURCE: n/a
3737// FORMAT THEOREM: ∀p∈Projects: reserved(port(p))
3838// PURITY: SHELL
39- // EFFECT: Effect<ReadonlyArray<ReservedPort>, PlatformError, FileSystem | Path>
39+ // EFFECT: Effect<ReadonlyArray<ReservedPort>, PlatformError | PortProbeError , FileSystem | Path. Path>
4040// INVARIANT: excludes the current project dir when provided
4141// COMPLEXITY: O(n) where n = number of projects
4242export const loadReservedPorts = (
4343 excludeDir : string | null
44- ) : Effect . Effect < ReadonlyArray < ReservedPort > , PlatformError , FileSystem | Path . Path > =>
44+ ) : Effect . Effect <
45+ ReadonlyArray < ReservedPort > ,
46+ PlatformError | PortProbeError ,
47+ FileSystem | Path . Path
48+ > =>
4549 Effect . gen ( function * ( _ ) {
4650 const path = yield * _ ( Path . Path )
4751 const items = yield * _ ( listProjectItems )
48- return items
49- . filter ( filterReserved ( path , excludeDir ) )
50- . map ( ( item ) => ( { port : item . sshPort , projectDir : item . projectDir } ) )
52+ const reserved : Array < ReservedPort > = [ ]
53+ const filter = filterReserved ( path , excludeDir )
54+
55+ for ( const item of items ) {
56+ if ( ! filter ( item ) ) {
57+ continue
58+ }
59+ if ( ! ( yield * _ ( isPortAvailable ( item . sshPort ) ) ) ) {
60+ reserved . push ( { port : item . sshPort , projectDir : item . projectDir } )
61+ }
62+ }
63+
64+ return reserved
5165 } )
5266
5367const isReserved = ( reserved : ReadonlySet < number > , port : number ) : boolean => reserved . has ( port )
0 commit comments