Skip to content

feat: give each worktree its own dev-server port - #126

Merged
omartelo merged 1 commit into
mainfrom
claude/issue-120-implementation-u7qfgx
Jul 28, 2026
Merged

omartelo merged 1 commit into
mainfrom
claude/issue-120-implementation-u7qfgx

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Two worktrees of one project both ran pnpm dev and both wanted the
framework's default port, so the second one lost — and the setup script
that had just installed the dependencies had no way to know it should
have picked another number.

Every session now starts with LICH_WORKTREE_PORT set to a port derived
from its checkout's path, so a setup script (or a command typed in the
terminal) reads PORT=$LICH_WORKTREE_PORT pnpm dev and both worktrees
come up. The port is a pure function of the path: the same checkout gets
the same number across restarts of the session and of lich.

The variable is derived from the session's start directory alone, so it
is exported even when the transport failed to start — unlike LICH_PORT,
which addresses that transport. It is deliberately not LICH_PORT: that
name is the hook listener (docs/hooks/README.md).

Nothing probes and nothing binds — two checkouts can hash to the same
number, and only the dev server started second finds out. Probing was
the alternative and it costs the stability that is the point: the
previous server still holding the port would move it on every restart.
Recorded as a Known Ceiling.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_018Rne8dofV1xs996xDBhRWH

Two worktrees of one project both ran `pnpm dev` and both wanted the
framework's default port, so the second one lost — and the setup script
that had just installed the dependencies had no way to know it should
have picked another number.

Every session now starts with LICH_WORKTREE_PORT set to a port derived
from its checkout's path, so a setup script (or a command typed in the
terminal) reads `PORT=$LICH_WORKTREE_PORT pnpm dev` and both worktrees
come up. The port is a pure function of the path: the same checkout gets
the same number across restarts of the session and of lich.

The variable is derived from the session's start directory alone, so it
is exported even when the transport failed to start — unlike LICH_PORT,
which addresses that transport. It is deliberately not LICH_PORT: that
name is the hook listener (docs/hooks/README.md).

Nothing probes and nothing binds — two checkouts can hash to the same
number, and only the dev server started second finds out. Probing was
the alternative and it costs the stability that is the point: the
previous server still holding the port would move it on every restart.
Recorded as a Known Ceiling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Rne8dofV1xs996xDBhRWH
@omartelo
omartelo merged commit 0192085 into main Jul 28, 2026
3 checks passed
@omartelo
omartelo deleted the claude/issue-120-implementation-u7qfgx branch July 28, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants