## What was done Replaced the strict `!nonEmpty(process.env.PORT)` guard in `maybePersistWorktreeRuntimePorts` with a new `isPortPinnedByRuntimeEnv` helper function. This function checks if `process.env.PORT` is set, but only suppresses persisting the port to configuration if the ambient `PORT` matches the newly allocated `selectedPort`. ## Why it matters Fixes issue #1849. Previously, if an ambient `PORT` environment variable was exported globally (like inheriting from the shell running the parent workspace), worktrees would silently fail to write their collision-avoiding ports (e.g. 3103 instead of 3100) back to their respective local `config.json` files. This resulted in orphaned sub-worktrees and lost port tracking on reboot. With this fix, worktrees correctly persist their assigned ports even while nested under an inherited environment variables stack, while continuing to respect manual, explicit pinning. ## How to verify 1. Export a port in the shell explicitly: `export PORT=3100`. 2. Launch a sub-worktree instance which receives an auto-assigned free port (e.g., `3103`). 3. View the underlying `config.json` for that worktree inside `.paperclip/worktrees/`. 4. The config file should correctly contain `{"server": {"port": 3103}}` rather than dropping the write operation. ## Risks None expected. The `Number()` and `Number.isInteger()` checks handle parsing edge cases cleanly, defaulting robustly to preventing writes if `process.env.PORT` is somehow malformed (e.g., set to a non-integer), ensuring absolute safety during misconfigurations. Co-authored-by: manavshrivastavagit <manavshrivastava@users.noreply.github.com>
This commit is contained in:
parent
19be4cf927
commit
ebf2b8ff79
|
|
@ -650,6 +650,14 @@ export function maybeRepairLegacyWorktreeConfigAndEnvFiles(): {
|
|||
return { repairedConfig, repairedEnv };
|
||||
}
|
||||
|
||||
function isPortPinnedByRuntimeEnv(rawValue: string | null | undefined, selectedPort: number): boolean {
|
||||
const normalized = nonEmpty(rawValue);
|
||||
if (!normalized) return false;
|
||||
const parsedPort = Number(normalized);
|
||||
if (!Number.isInteger(parsedPort) || parsedPort <= 0) return true;
|
||||
return parsedPort === selectedPort;
|
||||
}
|
||||
|
||||
export function maybePersistWorktreeRuntimePorts(input: {
|
||||
serverPort: number;
|
||||
databasePort?: number | null;
|
||||
|
|
@ -667,7 +675,7 @@ export function maybePersistWorktreeRuntimePorts(input: {
|
|||
const { config, changed } = applyRuntimePortSelectionToConfig(fileConfig, {
|
||||
serverPort: input.serverPort,
|
||||
databasePort: input.databasePort,
|
||||
allowServerPortWrite: !nonEmpty(process.env.PORT),
|
||||
allowServerPortWrite: !isPortPinnedByRuntimeEnv(process.env.PORT, input.serverPort),
|
||||
allowDatabasePortWrite: !nonEmpty(process.env.DATABASE_URL),
|
||||
});
|
||||
|
||||
|
|
@ -675,3 +683,4 @@ export function maybePersistWorktreeRuntimePorts(input: {
|
|||
writeConfigFile(context.configPath, config);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue