Skip to content

fix(win): tree-kill local PTYs so ports free on terminal stop - #10346

Open
innocarpe wants to merge 6 commits into
stablyai:mainfrom
innocarpe:fix/windows-terminal-port-tree-kill
Open

fix(win): tree-kill local PTYs so ports free on terminal stop#10346
innocarpe wants to merge 6 commits into
stablyai:mainfrom
innocarpe:fix/windows-terminal-port-tree-kill

Conversation

@innocarpe

@innocarpe innocarpe commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • On Windows, every local PTY stop runs taskkill /T /F on the ConPTY root before shell kill, so npm run dev / Vite children release listening ports.
  • Ports panel kill also tree-kills on Windows instead of single-PID process.kill.
  • POSIX keeps agent-only descendant snapshot kill; plain POSIX terminals still skip tree-kill so intentional nohup children survive.

Fixes #10150.

Why

Closing a terminal (or switching projects) on Windows only stopped the shell process. Child servers reparented and kept the port, so Project B appeared to serve Project A’s site.

Relationship to #10004 / #10100

Shares the Windows taskkill /T helper and killWithDescendantSweep branch. This PR applies tree-kill to all local Windows PTYs (not only agent sessions) and the Ports kill path, which is what frees dev-server ports. #10100 can be closed as partially superseded once this lands, or restacked to keep agent-specific POSIX notes.

Test plan

  • windows-process-tree-kill, pty-descendant-termination (incl. Windows sweep), workspace-port-ownership, local-pty-provider tests
  • pnpm typecheck:node
  • Manual on Windows: npm run dev in a worktree terminal → close tab → confirm port free / Project B binds cleanly; Ports UI Stop also frees port

Note: Re-opened as a new PR after an accidental empty force-push during local rebase cleanup closed the original #10183 (no code intent to withdraw). Branch tip restored with an empty recovery commit.

ELI5

Closing a terminal on Windows left child processes (like npm/Vite) holding ports. Local PTY stop now tree-kills the process tree so ports free immediately.

@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (4b3b450f5)

Rebased onto latest upstream/main after recovery; resolved conflicts in local-pty-provider (Windows tree-kill for all local PTYs) and tests.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@innocarpe, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd171cef-6bb7-4036-b138-de319d211e7e

📥 Commits

Reviewing files that changed from the base of the PR and between 7da9368 and e94e4a8.

📒 Files selected for processing (6)
  • src/main/ports/workspace-port-ownership.test.ts
  • src/main/ports/workspace-port-ownership.ts
  • src/main/providers/local-pty-provider.test.ts
  • src/main/providers/local-pty-provider.ts
  • src/main/pty-descendant-termination.test.ts
  • src/main/pty-descendant-termination.ts
📝 Walkthrough

Walkthrough

The change adds Windows workspace-port process-tree termination with retryable PID liveness checks and injectable delays. POSIX termination remains SIGTERM-based. PTY shutdown replaces descendant snapshots with asynchronous descendant sweeps and extends Windows cleanup to immediate shutdowns. Tests cover ownership checks, retry outcomes, shutdown coordination, and natural process exit. PTY launch handling removes default WSL and Windows environment fallbacks, simplifies session and PATH handling, and stops registering the startup echo probe.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes the summary and test plan but omits required AI Review Report, Security Audit, Screenshots, Notes, and most template test checks. Add every template section, report AI cross-platform review and security findings, state "No visual change", and record all executed test commands or explain skipped checks.
Out of Scope Changes check ⚠️ Warning The PR also changes WSL fallback, reattach IDs, attach-only spawning, PATH handling, and removes unrelated tests outside the linked issue objective. Remove unrelated behavioral changes and test deletions, or link them to separate issues and split them into focused pull requests.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Windows PTY tree-kill change that addresses port release.
Linked Issues check ✅ Passed The changes implement Windows process-tree termination for local PTYs and port kills, with liveness retries to free ports as required by [#10150].
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 178c6a60-1c8c-4c5a-b610-fe2cf3cc7ed0

📥 Commits

Reviewing files that changed from the base of the PR and between 981653f and a5cce6f.

📒 Files selected for processing (8)
  • src/main/ports/workspace-port-ownership.test.ts
  • src/main/ports/workspace-port-ownership.ts
  • src/main/providers/local-pty-provider.test.ts
  • src/main/providers/local-pty-provider.ts
  • src/main/pty-descendant-termination.test.ts
  • src/main/pty-descendant-termination.ts
  • src/main/windows-process-tree-kill.test.ts
  • src/main/windows-process-tree-kill.ts

Comment thread src/main/ports/workspace-port-ownership.test.ts
Comment thread src/main/ports/workspace-port-ownership.ts
@AmethystLiang
AmethystLiang requested a review from OrcaWin July 24, 2026 16:49
@innocarpe
innocarpe force-pushed the fix/windows-terminal-port-tree-kill branch from 4b3b450 to 8d56dd0 Compare July 25, 2026 10:34
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (274473faa)

Address CodeRabbit: retry Windows liveness probe after taskkill (PID may linger until handles drain); platform restore already in finally

@nwparker nwparker added the bug Something isn't working label Jul 27, 2026
@innocarpe
innocarpe force-pushed the fix/windows-terminal-port-tree-kill branch from 274473f to 1ad4b84 Compare July 27, 2026 15:24
@innocarpe
innocarpe force-pushed the fix/windows-terminal-port-tree-kill branch from 1ad4b84 to e8060f1 Compare August 6, 2026 03:42
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (e8060f107e)

Rebase onto latest upstream/main: Windows tree-kill for ports/PTYs; keep requireMetadata re-scan; identity-probe-safe tests.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 104cb2b8-f6f5-4f9a-b795-d5824ed83219

📥 Commits

Reviewing files that changed from the base of the PR and between ff01fad and e8060f1.

📒 Files selected for processing (6)
  • src/main/ports/workspace-port-ownership.test.ts
  • src/main/ports/workspace-port-ownership.ts
  • src/main/providers/local-pty-provider.test.ts
  • src/main/providers/local-pty-provider.ts
  • src/main/pty-descendant-termination.test.ts
  • src/main/pty-descendant-termination.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/pty-descendant-termination.test.ts

Comment thread src/main/providers/local-pty-provider.ts Outdated
On Windows, ConPTY shell-only kill left npm/dev-server children listening,
so switching projects could still serve the previous app on the same port.

- taskkill /T /F via killWithDescendantSweep for every local PTY stop on Windows
- Ports UI kill path also tree-kills on Windows
- Keep POSIX agent-only descendant sweep; plain POSIX terminals unchanged

Closes stablyai#10150
Related: overlaps Windows agent path of stablyai#10004 / stablyai#10100
terminateWindowsProcessTree is best-effort and always resolves so PTY
teardown is never blocked. Ports UI needs a real outcome: after taskkill,
probe liveness with process.kill(pid, 0) and return failure if the PID
is still alive.

Addresses CodeRabbit review on stablyai#10183.
EPERM from process.kill(pid, 0) means the process is still alive without
signal rights; do not report Ports kill success in that case.

Addresses CodeRabbit follow-up on stablyai#10183.
… rebase cleanup

No code change. Re-opens the contribution for review after branch recovery.
…ession tests

Preserve WorkspacePortScanOptions on scanWorkspacePortProbes and re-add the
authorizing re-scan metadata tests dropped during conflict resolution, while
keeping Windows tree-kill liveness probes for stablyai#10150.
@innocarpe
innocarpe force-pushed the fix/windows-terminal-port-tree-kill branch from e8060f1 to e94e4a8 Compare August 6, 2026 04:16
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (e94e4a8e8f)

Sync update

Rebased onto latest upstream/main and resolved conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Port is not released after stopping/switching project, causing new project to route to previous site

3 participants