Skip to content

feat(desktop): add ability to close ports from ports list#797

Merged
Kitenite merged 7 commits into
mainfrom
allow-closing-ports-from-ports
Jan 18, 2026
Merged

feat(desktop): add ability to close ports from ports list#797
Kitenite merged 7 commits into
mainfrom
allow-closing-ports-from-ports

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Jan 18, 2026

Summary

  • Add close button (X) on individual port badges to kill the process listening on that port
  • Add "Close all" button next to each workspace name to kill all active ports for that workspace
  • Extract port killing logic into shared useKillPort hook

Test plan

  • Open a dev server in a terminal (e.g., bun dev)
  • Verify the port appears in the ports sidebar
  • Hover over the port badge and verify the X button appears
  • Click the X button and verify the process is killed
  • Hover over the workspace name and verify the "Close all" X button appears
  • Click "Close all" and verify all ports for that workspace are closed

Summary by CodeRabbit

  • New Features
    • Added ability to terminate individual active ports directly from the ports list.
    • Added close-all button to simultaneously terminate all active ports within a workspace group.
    • Integrated port termination UI with X icon buttons for convenient port management.

✏️ Tip: You can customize this high-level summary in your review settings.

Add close buttons to the ports sidebar section allowing users to kill
processes listening on specific ports directly from the UI.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 18, 2026

Warning

Rate limit exceeded

@Kitenite has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 54 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8f4d34f and 4dcfa49.

📒 Files selected for processing (5)
  • apps/desktop/src/lib/trpc/routers/ports/ports.ts
  • apps/desktop/src/main/lib/terminal/port-manager.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/components/MergedPortBadge/MergedPortBadge.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/components/WorkspacePortGroup/WorkspacePortGroup.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/useKillPort.ts
📝 Walkthrough

Walkthrough

This PR adds process termination capability to the ports management system. It introduces a new TRPC endpoint that kills processes by PID, a React hook managing port termination with error handling, and UI buttons in the sidebar to close individual ports or entire workspace port groups.

Changes

Cohort / File(s) Summary
TRPC Backend
apps/desktop/src/lib/trpc/routers/ports/ports.ts
New kill publicProcedure accepts PID input and terminates process via process.kill() with SIGTERM; returns success status with optional error message; adds node:process import.
Port Termination Hook
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/useKillPort.ts
New useKillPort hook provides killPort() for single port termination and killPorts() for concurrent multi-port termination; wires TRPC mutation, filters active ports, displays error toast on failure, exposes isPending state.
UI Components
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/components/MergedPortBadge/MergedPortBadge.tsx,
apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/components/WorkspacePortGroup/WorkspacePortGroup.tsx
MergedPortBadge adds close button (LuX icon) to terminate individual ports when active with PID. WorkspacePortGroup adds close-all button with tooltip to terminate all active ports in group; refactors layout to accommodate optional close control.

Sequence Diagram

sequenceDiagram
    actor User
    participant UI as UI Component<br/>(MergedPortBadge/<br/>WorkspacePortGroup)
    participant Hook as useKillPort<br/>Hook
    participant TRPC as TRPC Client
    participant Server as Backend<br/>ports.ts
    participant Process as Node<br/>Process
    participant Toast as Toast<br/>Notification

    User->>UI: Click close port(s) button
    UI->>Hook: killPort(port) or killPorts(ports)
    Hook->>Hook: Filter active ports with PID
    Hook->>TRPC: Call electronTrpc.kill({ pid })
    TRPC->>Server: Send kill mutation request
    Server->>Process: process.kill(pid, 'SIGTERM')
    alt Success
        Process-->>Server: Process terminated
        Server-->>TRPC: { success: true }
        TRPC-->>Hook: Success response
        Hook->>Toast: Show success (implicit)
    else Failure
        Process-->>Server: Error occurred
        Server-->>TRPC: { success: false, error: "..." }
        TRPC-->>Hook: Error response
        Hook->>Toast: Show error message
    end
    Toast->>User: Display result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hop, skip, and a terminate!
Close those ports with just a click,
No more lingering processes—zip, zip, quick!
From sidebar buttons bright and true,
We bid those pesky ports adieu.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature: adding the ability to close ports from the ports list UI.
Description check ✅ Passed The description provides a clear summary, includes a test plan with specific verification steps, but lacks the template structure with sections like Related Issues and Type of Change.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

Add text-muted-foreground base color and hover states to external link
(hover:text-primary) and close (hover:text-destructive) buttons.
@Kitenite Kitenite force-pushed the allow-closing-ports-from-ports branch from b87c77e to 3b85a1c Compare January 18, 2026 00:18
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@apps/desktop/src/lib/trpc/routers/ports/ports.ts`:
- Line 1: The PID schema currently uses z.object({ pid: z.number() }) which
allows decimals, zero and negatives and can cause dangerous process-group
signalling when used with process.kill; update the schema (in ports.ts where the
PID input is defined/used) to require a positive integer (e.g., use
z.number().int().positive() or z.number().int().min(1) / z.int().positive()) so
only valid PIDs >= 1 are accepted, and ensure any handler that calls
process.kill() uses this validated value.

In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/useKillPort.ts`:
- Around line 5-35: The killPort and killPorts functions in useKillPort can
throw unhandled rejections from killMutation.mutateAsync; wrap both killPort and
killPorts bodies in try/catch blocks, log errors with a “[ports/kill]” prefix
using console.error (or the project logger) and show user-facing toasts on
failure; in killPorts use Promise.allSettled instead of Promise.all to allow all
mutations to run, then treat settled results by filtering both rejected promises
and settled values where result.success === false, and surface the total
failures in the toast; keep the function names (useKillPort, killPort,
killPorts) and the killMutation.mutateAsync calls but add the described error
handling and logging.

Comment thread apps/desktop/src/lib/trpc/routers/ports/ports.ts Outdated
- Move process.kill logic to portManager.killPort()
- Accept paneId + port instead of raw PID from client
- Verify PID is not the terminal shell before killing
- Only kill processes tracked in our ports map
@Kitenite
Copy link
Copy Markdown
Collaborator Author

feat(desktop): improve port management UI with close buttons and safer process handling
Add ability to close ports from the ports sidebar, allowing users to kill processes listening on specific ports directly from the UI.

Add close buttons to ports sidebar with improved interaction patterns
Enhance button styling with hover states (destructive for close, primary for external link)
Increase port action button size for better usability
Add spacing between port tooltip and target element
Validate PID as positive integer to prevent invalid process signalling
Refactor to safer port killing via portManager:

Move process.kill logic to dedicated portManager.killPort() method
Accept paneId + port instead of raw PID from client
Verify PID is not the terminal shell before killing
Only kill processes tracked in ports map

@Kitenite Kitenite merged commit 43ca468 into main Jan 18, 2026
5 checks passed
@Kitenite Kitenite deleted the allow-closing-ports-from-ports branch January 18, 2026 00:29
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch
  • ⚠️ Electric Fly.io app

Thank you for your contribution! 🎉

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.

1 participant