### Swift Type Inference Example Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates the use of type inference in Swift for improved readability. It shows when to use inferred types and when explicit types add clarity. ```swift // Good - type is clear from context let ports = scanner.scanPorts() let count = ports.count // Avoid - unnecessary explicit type let ports: [PortInfo] = scanner.scanPorts() // Good - explicit type adds clarity let timeout: TimeInterval = 5.0 ``` -------------------------------- ### Property Documentation (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Documents non-obvious properties with descriptive comments, explaining their purpose and any associated behavior, like synchronization with `UserDefaults`. This improves clarity on state management. ```swift /// Cached favorites set, synced with UserDefaults private var _favorites: Set = Defaults[.favorites] { didSet { Defaults[.favorites] = _favorites } } /// Whether a port scan is currently in progress var isScanning = false ``` -------------------------------- ### File Header Structure (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Specifies the standard header for Swift files, starting with necessary imports, followed by MARK comments for code organization. Includes an example of documenting a struct with JSDoc-style comments. ```swift import Foundation import SwiftUI import Defaults // MARK: - Model Definition /** * PortInfo represents a process listening on a network port. */ struct PortInfo: Identifiable, Sendable { // ... } ``` -------------------------------- ### System Command Execution in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Provides a robust pattern for executing system commands asynchronously in Swift. It handles process creation, argument passing, and capturing standard output. ```swift func runCommand(path: String, args: [String]) async -> String? { let process = Process() process.executableURL = URL(fileURLWithPath: path) process.arguments = args let pipe = Pipe() process.standardOutput = pipe process.standardError = FileHandle.nullDevice do { try process.run() let data = pipe.fileHandleForReading.readDataToEndOfFile() process.waitUntilExit() return String(data: data, encoding: .utf8) } catch { return nil } } ``` -------------------------------- ### Singleton-like Manager Pattern in Swift (SwiftUI) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Presents a pattern for creating app-wide managers using `@Observable` and `@MainActor` for shared state accessible throughout a SwiftUI application. ```swift @Observable @MainActor final class AppState { // Shared state accessible throughout the app } // Usage in SwiftUI @Environment(AppState.self) private var appState ``` -------------------------------- ### SwiftUI State Management with @Observable Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates modern SwiftUI state management using the `@Observable` macro. It contrasts this with the legacy `ObservableObject` pattern, recommending the newer approach. ```swift // Good - Modern @Observable @Observable @MainActor final class AppState { var ports: [PortInfo] = [] var isScanning = false } // Avoid - Legacy ObservableObject @MainActor final class AppState: ObservableObject { @Published var ports: [PortInfo] = [] @Published var isScanning = false } ``` -------------------------------- ### Arrange-Act-Assert Test Structure in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Shows the standard Arrange-Act-Assert pattern for structuring unit tests. This promotes clarity and consistency in how tests are written and executed. ```swift @Test("Port range filter excludes ports outside range") func portRangeFilter() { // Arrange var filter = PortFilter() filter.minPort = 3000 filter.maxPort = 5000 // Act let portInRange = createPort(port: 4000) let portOutOfRange = createPort(port: 6000) // Assert #expect(filter.matches(portInRange, favorites: [], watched: [])) #expect(!filter.matches(portOutOfRange, favorites: [], watched: [])) } ``` -------------------------------- ### Swift Naming Conventions: Constants Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Shows the recommended Swift practice for defining constants using static properties within enums, grouping related constants for better organization. ```swift // Good enum UIConstants { static let width: CGFloat = 340 static let maxHeight: CGFloat = 400 } // Avoid let MENU_BAR_WIDTH = 340 // Wrong case let menuBarWidth = 340 // Should be grouped with related constants ``` -------------------------------- ### Swift Naming Conventions: Enum Cases Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates Swift enum case naming conventions, advocating for lowercase and omitting redundant prefixes when the context is clear. ```swift // Good enum ProcessType { case webServer case database case development } let type: ProcessType = .webServer // Context clear // Avoid enum ProcessType { case ProcessTypeWebServer // Redundant prefix case process_type_database // Wrong case } ``` -------------------------------- ### File Structure Organization (Project) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates a recommended file structure for organizing code by feature and responsibility. This promotes modularity and maintainability within the project. Includes directories for models, managers, services, and views. ```plaintext Sources/ ├── PortKillerApp.swift # App entry point ├── AppState.swift # Main app state ├── Constants.swift # App constants ├── Models/ # Data models │ ├── Models.swift │ └── PortFilter.swift ├── Managers/ # Business logic │ ├── UpdateManager.swift │ └── SponsorManager.swift ├── Services/ # External services │ └── SponsorsService.swift ├── Views/ # UI components │ ├── MainWindowView.swift │ ├── SettingsView.swift │ └── Components/ │ ├── PortTableView.swift │ └── AddPortPopover.swift └── PortScanner.swift # Port scanning logic ``` -------------------------------- ### Swift Error Handling with try? and do-catch Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates Swift error handling strategies. It shows using `try?` for non-critical operations where failure is acceptable, and `do-catch` for critical operations requiring explicit error management. ```swift // Good - we don't care if this fails try? await Task.sleep(for: .milliseconds(500)) // Good - critical operation, handle errors do { try process.run() process.waitUntilExit() } catch { print("Failed to run process: (error)") return false } ``` -------------------------------- ### Swift Guard Statement for Early Returns Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Shows the recommended use of Swift's `guard` statement for early returns, improving code clarity and reducing nesting compared to traditional if-else structures. ```swift // Good guard let port = selectedPort else { return } // Use port here... // Avoid if selectedPort != nil { let port = selectedPort! // Use port here... } ``` -------------------------------- ### Swift Naming Conventions: Variables and Functions Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates Swift naming conventions for variables, functions, and parameters using camelCase. It emphasizes that boolean variables should read as assertions. ```swift // Good var isScanning = false var canCheckForUpdates = true func killProcess(pid: Int) { } // Avoid var scanning = false // Unclear type var able_to_check = true // Wrong case func kill(p: Int) { } // Unclear parameter ``` -------------------------------- ### MARK Comments for Code Organization (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates the use of `// MARK:` comments to logically group code within Swift files. This improves readability and navigation by categorizing properties, initializers, public methods, and private methods. ```swift class AppState { // MARK: - Properties var ports: [PortInfo] = [] // MARK: - Initialization init() { } // MARK: - Port Operations func refresh() async { } func killPort(_ port: PortInfo) async { } // MARK: - Favorites func toggleFavorite(_ port: Int) { } // MARK: - Private Methods private func updatePorts(_ newPorts: [PortInfo]) { } } Standard sections (in order): 1. Properties 2. Initialization 3. Public Methods (grouped by feature) 4. Private Methods ``` -------------------------------- ### Descriptive Test Naming in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates the importance of using descriptive names for tests to clearly indicate their purpose. This enhances the understandability of the test suite. ```swift @Test("Detects nginx as web server") func detectNginx() { #expect(ProcessType.detect(from: "nginx") == .webServer) } @Test("Search matches process name case insensitively") func searchMatchesProcessNameCaseInsensitive() { let filter = PortFilter(searchText: "NODE") let port = createPort(processName: "node") #expect(filter.matches(port, favorites: [], watched: [])) } ``` -------------------------------- ### Install PortKiller via Homebrew (macOS) Source: https://context7.com/productdevbook/port-killer/llms.txt Installs PortKiller on macOS using the Homebrew package manager. Alternatively, users can download the .dmg file from GitHub Releases. ```bash # Install PortKiller using Homebrew brew install --cask productdevbook/tap/portkiller # Or download .dmg from GitHub Releases open https://github.com/productdevbook/port-killer/releases ``` -------------------------------- ### SwiftUI View Structure: Extracting Complex Views Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates the practice of extracting complex or reusable view components into separate, focused views in SwiftUI. This improves maintainability and readability. ```swift // Good struct PortDetailView: View { let port: PortInfo var body: some View { VStack { PortHeader(port: port) PortInfo(port: port) PortActions(port: port) } } } // Each component is focused and reusable ``` -------------------------------- ### Line Length Best Practices (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Advises on maintaining code readability by keeping lines under 120 characters. Demonstrates how to break long function calls into multiple lines for better visual organization. ```swift // Good let controller = SPUStandardUpdaterController( startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil ) // Avoid - too long let controller = SPUStandardUpdaterController(startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil) ``` -------------------------------- ### Function Length and Structure in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates keeping functions concise and extracting complex logic into helper functions. This improves readability and maintainability by adhering to a maximum function length of 50 lines. ```swift // Good func parseLsofOutput(_ output: String) -> [PortInfo] { let lines = output.components(separatedBy: .newlines) var ports: [PortInfo] = [] for line in lines.dropFirst() { guard let port = parseLineToPort(line) else { continue } ports.append(port) } return ports } private func parseLineToPort(_ line: String) -> PortInfo? { // Focused parsing logic } ``` -------------------------------- ### Swift Naming Conventions: Types Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates correct Swift naming conventions for types (structs, classes, enums, protocols) using PascalCase and descriptive names, contrasting with common avoidance patterns. ```swift // Good struct PortInfo { } class AppState { } enum ProcessType { } protocol PortScanning { } // Avoid struct PI { } class AS { } enum PT { } ``` -------------------------------- ### JSDoc-Style API Documentation (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Documents public APIs using JSDoc-style comments, providing clear explanations of function purpose, parameters, return values, and any associated commands. This enhances code understanding and maintainability. ```swift /** * Scans all listening TCP ports using lsof. * * Executes: `lsof -iTCP -sTCP:LISTEN -P -n +c 0` * * @returns Array of PortInfo objects representing all listening ports */ func scanPorts() async -> [PortInfo] { // Implementation } /** * Kills a process by sending a termination signal. * * @param pid - The process ID to kill * @param force - If true, sends SIGKILL (-9) instead of SIGTERM (-15) * @returns True if the kill command executed successfully */ func killProcess(pid: Int, force: Bool = false) async -> Bool { // Implementation } ``` -------------------------------- ### SwiftUI Custom View Modifiers Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates how to create and use custom view modifiers in SwiftUI for applying repeated styling and behavior to views, promoting code reuse and consistency. ```swift // Good struct CardStyle: ViewModifier { func body(content: Content) -> some View { content .padding() .background(Color.white) .cornerRadius(8) } } extension View { func cardStyle() -> some View { modifier(CardStyle()) } } // Usage Text("Hello").cardStyle() ``` -------------------------------- ### UserDefaults Integration with Cached Properties in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates integrating `UserDefaults` with cached properties for efficient access to user defaults. This pattern uses a backing private variable that synchronizes with `UserDefaults`. ```swift // In Defaults.Keys extension static let favorites = Key>("favorites", default: []) // In AppState private var _favorites: Set = Defaults[.favorites] { didSet { Defaults[.favorites] = _favorites } } var favorites: Set { get { _favorites } set { _favorites = newValue } } ``` -------------------------------- ### Swift Optional Chaining and Nil Coalescing Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates preferred Swift patterns for handling optionals using optional chaining and the nil coalescing operator. It contrasts this with less concise if-let blocks. ```swift // Good let name = port.processName ?? "Unknown" window?.makeKeyAndOrderFront(nil) // Avoid if let processName = port.processName { name = processName } else { name = "Unknown" } ``` -------------------------------- ### DRY Principle: Code Extraction in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Demonstrates the 'Don't Repeat Yourself' principle by extracting repeated code into reusable functions. This reduces redundancy and simplifies future modifications. ```swift // Good func createPort(port: Int, processName: String) -> PortInfo { PortInfo.active( port: port, pid: 0, processName: processName, address: "127.0.0.1", user: "user", command: processName, fd: "19u" ) } let nodePort = createPort(port: 3000, processName: "node") let nginxPort = createPort(port: 8080, processName: "nginx") ``` -------------------------------- ### Code Complexity Management in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Illustrates avoiding deeply nested conditional statements by using early returns. This pattern enhances code clarity and reduces the cognitive load required to understand the control flow. ```swift // Good - Early returns guard !line.isEmpty else { continue } guard components.count >= 9 else { continue } guard let pid = Int(components[1]) else { continue } // Avoid - Nested ifs if !line.isEmpty { if components.count >= 9 { if let pid = Int(components[1]) { // Deep nesting... } } } ``` -------------------------------- ### SwiftUI View Structure: Single Responsibility Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Highlights the SwiftUI pattern of keeping views focused on a single responsibility and maintaining a manageable line count (under 200). It shows a well-structured `PortListView`. ```swift // Good - Single responsibility struct PortListView: View { let ports: [PortInfo] var body: some View { List(ports) { port in PortRowView(port: port) } } } // Avoid - Too many responsibilities struct MainView: View { var body: some View { // 500 lines of nested views... } } ``` -------------------------------- ### Avoiding Magic Numbers in Swift Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Promotes the use of named constants instead of literal magic numbers for improved code readability and maintainability. This makes the code self-documenting and easier to update. ```swift // Good enum AppConstants { static let defaultRefreshInterval: Int = 5 static let maxCommandLength: Int = 200 } let interval = AppConstants.defaultRefreshInterval // Avoid try? await Task.sleep(for: .seconds(5)) // Why 5? let trimmed = command.prefix(200) // Why 200? ``` -------------------------------- ### Expose Local Ports with Cloudflare Quick Tunnels (Swift) Source: https://context7.com/productdevbook/port-killer/llms.txt Creates Cloudflare Quick Tunnels to expose local ports to the internet. This utility automatically copies the tunnel URL to the clipboard and provides status notifications. It checks for the cloudflared installation and allows managing individual or all tunnels. ```swift // Cloudflare Tunnels - Expose local ports via cloudflared import Foundation @MainActor class TunnelController { let tunnelManager = TunnelManager() func manageTunnels() { // Check if cloudflared is installed if !tunnelManager.isCloudflaredInstalled { print("Install with: brew install cloudflared") return } // Start a tunnel for a local port tunnelManager.startTunnel(for: 3000) // Get tunnel status if let tunnel = tunnelManager.tunnelState(for: 3000) { switch tunnel.status { case .starting: print("Tunnel starting...") case .active: print("Tunnel URL: \(tunnel.tunnelURL ?? "N/A")") print("Started: \(tunnel.startTime ?? Date())") case .error: print("Error: \(tunnel.lastError ?? "Unknown")") case .stopping: print("Tunnel stopping...") } } // Copy URL to clipboard tunnelManager.copyURL(for: 3000) // Open in browser tunnelManager.openURL(for: 3000) // Stop tunnel tunnelManager.stopTunnel(for: 3000) // Stop all tunnels Task { await tunnelManager.stopAllTunnels() } // Active tunnel count print("Active tunnels: \(tunnelManager.activeTunnelCount)") } } ``` -------------------------------- ### Get Process Command Line (C#) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This C# code snippet shows how to retrieve the command line arguments for a given process ID using Windows Management Instrumentation (WMI). This is used to gather detailed process information. ```csharp // Get command line ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = {pid}") ``` -------------------------------- ### Task Management for Cancellable Operations (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Manages asynchronous tasks that may need to be cancelled, such as background refresh operations. Stores the `Task` instance to allow for cancellation via `task.cancel()`. Ensures cleanup in `deinit`. ```swift // Good @ObservationIgnored private nonisolated(unsafe) var refreshTask: Task? func startAutoRefresh() { refreshTask = Task { while !Task.isCancelled { await refresh() try? await Task.sleep(for: .seconds(5)) } } } deinit { refreshTask?.cancel() } ``` -------------------------------- ### Get Process Owner (C#) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This C# code snippet illustrates how to obtain the owner of a process using Windows API calls like OpenProcessToken and WindowsIdentity. This is part of gathering detailed process information. ```csharp // Get process owner OpenProcessToken() + WindowsIdentity ``` -------------------------------- ### Manage Kubernetes Port Forwarding with Auto-Reconnect (Swift) Source: https://context7.com/productdevbook/port-killer/llms.txt Manages kubectl port-forward sessions with features like auto-reconnect, connection logging, and optional socat proxy support. It allows for creating, starting, stopping, and monitoring port-forward connections, as well as handling stuck processes. ```swift // Kubernetes Port Forwarding - Create and manage kubectl port-forward import Foundation @MainActor class K8sController { let portForwardManager = PortForwardManager() func setupPortForward() { // Create a port-forward configuration let config = PortForwardConnectionConfig( name: "API Server", namespace: "default", service: "api-service", localPort: 8080, remotePort: 80, proxyPort: nil, // Optional socat proxy port isEnabled: true, autoReconnect: true, useDirectExec: true, // kubectl exec + socat mode notifyOnConnect: true, notifyOnDisconnect: true ) // Add and start connection portForwardManager.addConnection(config) portForwardManager.startConnection(config.id) // Monitor connection state if let state = portForwardManager.connection(for: config.id) { print("Status: \(state.portForwardStatus.rawValue)") print("Connected: \(state.isFullyConnected)") print("Effective port: \(state.effectivePort)") // View logs for log in state.logs { print("[\(log.timestamp)] \(log.message)") } } // Bulk operations portForwardManager.startAll() portForwardManager.stopAll() // Handle stuck processes Task { await portForwardManager.killStuckProcesses() } } } ``` -------------------------------- ### Inline Comments for Complex Logic (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Uses inline comments to clarify intricate or critical sections of code, such as potential deadlocks or buffer issues. This helps developers understand the reasoning behind specific implementation choices. ```swift // CRITICAL: Read data BEFORE waitUntilExit to avoid deadlock // If pipe buffer fills up, ps will block waiting to write more data. let data = pipe.fileHandleForReading.readDataToEndOfFile() process.waitUntilExit() ``` -------------------------------- ### Actor for Thread-Safe State Management (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Utilizes actors to manage state in a thread-safe manner. Actors provide built-in protection against data races, making concurrent operations safer. Methods within an actor are executed sequentially. ```swift // Good actor PortScanner { func scanPorts() async -> [PortInfo] { // Thread-safe by default } func killProcess(pid: Int) async -> Bool { // Thread-safe by default } } ``` -------------------------------- ### Sendable Type for Concurrency Boundaries (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Marks data structures as `Sendable` to indicate they can be safely passed between different concurrency domains (e.g., actors, threads). This is crucial for maintaining data integrity when sharing information across concurrent tasks. ```swift // Good struct PortInfo: Sendable { let port: Int let pid: Int let processName: String } // Model can be safely passed between actors ``` -------------------------------- ### MainActor Isolation for UI-Related Types (Swift) Source: https://github.com/productdevbook/port-killer/blob/main/STYLE_GUIDE.md Ensures UI-related types and their operations run on the main thread to prevent crashes. Mark types with `@MainActor` to automatically dispatch their methods to the main thread. Avoid performing UI updates on background threads. ```swift // Good @Observable @MainActor final class AppState { var ports: [PortInfo] = [] func refresh() async { // Runs on main thread automatically ports = await scanner.scanPorts() } } // Avoid @Observable final class AppState { var ports: [PortInfo] = [] func refresh() async { // May run on background thread - UI updates will crash ports = await scanner.scanPorts() } } ``` -------------------------------- ### Get Extended TCP Table API (C#) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This C# code snippet demonstrates the use of the Windows GetExtendedTcpTable API to retrieve all listening TCP connections along with their associated process IDs. This is a core part of the port scanning functionality in PortKiller. ```csharp // Get all listening TCP connections with process IDs GetExtendedTcpTable(IntPtr, ref int, bool, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0); ``` -------------------------------- ### Build macOS Application Source: https://github.com/productdevbook/port-killer/blob/main/CONTRIBUTING.md Instructions for building the Port Killer application on macOS using Swift. It covers building for debug, release, and creating an app bundle using a script. ```bash cd platforms/macos swift build # Debug swift build -c release # Release ./scripts/build-app.sh # App bundle ``` -------------------------------- ### Clone and Navigate Project Repository Source: https://github.com/productdevbook/port-killer/blob/main/CONTRIBUTING.md This snippet shows how to clone the Port Killer project from GitHub and navigate into the project directory. It's the initial step for setting up the development environment. ```bash git clone https://github.com/productdevbook/port-killer.git cd port-killer ``` -------------------------------- ### Build and Run macOS Application Source: https://github.com/productdevbook/port-killer/blob/main/CONTRIBUTING.md Provides instructions for building and running the Port Killer application on macOS. It includes options for using Xcode or a build script, and notes that `swift run` is not suitable for menu bar apps. ```bash cd platforms/macos # Option 1: Xcode (recommended) open Package.swift # Press ▶️ to run # Option 2: Build script ./scripts/build-app.sh && open .build/apple/Products/Release/PortKiller.app ``` -------------------------------- ### Build Windows Application Source: https://github.com/productdevbook/port-killer/blob/main/CONTRIBUTING.md This section provides commands for building the Port Killer application on Windows using the .NET CLI. It includes options for building in debug mode and publishing a release version for a specific runtime. ```bash cd platforms/windows/PortKiller dotnet build # Debug dotnet publish -c Release -r win-x64 # Release ``` -------------------------------- ### Windows Build Process (Bash/Dotnet) Source: https://context7.com/productdevbook/port-killer/llms.txt Steps to build the Windows WPF application for PortKiller. It covers running the application in development mode and building a release version using `dotnet build` and `dotnet publish`. ```bash # Build Windows WPF app cd port-killer/platforms/windows/PortKiller # Run in development donet run # Build release donet build # Debug build donet publish -c Release -r win-x64 # Release build # Output: bin/Release/net9.0-windows/win-x64/publish/ ``` -------------------------------- ### Run Windows Application Source: https://github.com/productdevbook/port-killer/blob/main/CONTRIBUTING.md This snippet details how to run the Port Killer application on Windows using the .NET CLI. It requires navigating to the project directory and executing the `dotnet run` command. ```bash cd platforms/windows/PortKiller dotnet run ``` -------------------------------- ### macOS Build and Run Process (Bash) Source: https://context7.com/productdevbook/port-killer/llms.txt Instructions for cloning the PortKiller repository and building the macOS application. It includes options for building and running via Xcode or using a build script to create a universal binary app bundle. ```bash # Clone and build macOS app git clone https://github.com/productdevbook/port-killer.git cd port-killer/platforms/macos # Option 1: Build and run via Xcode (recommended) open Package.swift # Press Run button in Xcode # Option 2: Build script (creates universal binary app bundle) ./scripts/build-app.sh # Open the built app open .build/apple/Products/Release/PortKiller.app # Install to Applications cp -r .build/apple/Products/Release/PortKiller.app /Applications/ # Build commands (without app bundle) swift build # Debug build swift build -c release # Release build ``` -------------------------------- ### Build PortKiller from Source Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md These commands restore project dependencies and build the PortKiller application from its source code. This is part of the process for building the application locally. ```bash dotnet restore dotnet build ``` -------------------------------- ### Git Workflow for Pull Requests Source: https://github.com/productdevbook/port-killer/blob/main/CONTRIBUTING.md Outlines the standard Git workflow for submitting contributions via pull requests. This includes forking the repository, creating a feature branch, making changes, committing, and pushing. ```bash 1. Fork the repo 2. Create a branch (`git checkout -b feature/my-feature`) 3. Make changes and test locally 4. Commit (`git commit -m "feat: add feature"`) 5. Push and create PR ``` -------------------------------- ### Run Unit Tests (C#) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This command executes the unit tests for the PortKiller project. It is used to ensure the application's components are functioning correctly. ```csharp dotnet test ``` -------------------------------- ### Run PortKiller from Source Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This command executes the PortKiller application after it has been built from source. It allows for testing the application directly from the command line. ```bash dotnet run ``` -------------------------------- ### Clone PortKiller Repository Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This command clones the PortKiller project repository from GitHub to your local machine. It is the first step in building the application from source. ```bash git clone https://github.com/productdevbook/port-killer.git cd port-killer/platforms/windows ``` -------------------------------- ### Force Kill Process Tree (C#) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This C# code snippet demonstrates how to forcefully terminate a process and its entire process tree. It's a two-stage approach used by PortKiller, with graceful shutdown attempted first. ```csharp Process.Kill(entireProcessTree: true) ``` -------------------------------- ### Build PortKiller for Debug (C#) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This command builds the PortKiller application in Debug configuration. It is used during the development phase to create a debuggable version of the application. ```csharp dotnet build -c Debug ``` -------------------------------- ### Package PortKiller for Distribution (Single File) Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This command publishes the PortKiller application as a single, self-contained executable for the win-x64 platform. This simplifies distribution and deployment. ```csharp dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true ``` -------------------------------- ### Detect Process Type from Name (Swift) Source: https://context7.com/productdevbook/port-killer/llms.txt An enum that automatically categorizes processes based on a predefined list of well-known process names. This enables smart filtering and visual organization within the UI. It provides raw value strings and SF Symbol names for icons. ```swift // ProcessType Detection - Automatic process categorization import Foundation // Detect process type from name let webServer = ProcessType.detect(from: "nginx") // .webServer let database = ProcessType.detect(from: "postgres") // .database let devTool = ProcessType.detect(from: "node") // .development let system = ProcessType.detect(from: "launchd") // .system let other = ProcessType.detect(from: "myapp") // .other // Access properties print(webServer.rawValue) // "Web Server" print(webServer.icon) // "globe" (SF Symbol name) // Categorized process lists: // Web Servers: nginx, apache, httpd, caddy, traefik, lighttpd // Databases: postgres, mysql, mariadb, redis, mongo, sqlite, cockroach, clickhouse // Development: node, npm, yarn, python, ruby, php, java, go, cargo, swift, vite, webpack // System: launchd, rapportd, sharingd, airplay, control, kernel, mds, spotlight // Use in filtering let ports: [PortInfo] = await scanner.scanPorts() let databases = ports.filter { $0.processType == .database } let devPorts = ports.filter { $0.processType == .development } ``` -------------------------------- ### Package PortKiller for Distribution Source: https://github.com/productdevbook/port-killer/blob/main/platforms/windows/README.md This command publishes the PortKiller application for distribution. It creates a self-contained executable for the win-x64 platform, suitable for deployment. ```bash dotnet publish -c Release -r win-x64 --self-contained ``` -------------------------------- ### MainViewModel for MVVM State Management (Windows) Source: https://context7.com/productdevbook/port-killer/llms.txt The MainViewModel class implements MVVM-based state management for Windows WPF applications, mirroring the functionality of macOS AppState. It integrates services for port scanning, process killing, settings, and notifications. ```csharp // MainViewModel - Windows MVVM state management using PortKiller.ViewModels; using PortKiller.Services; // Initialize in app startup var scanner = new PortScannerService(); var killer = new ProcessKillerService(); var settings = new SettingsService(); var notifications = new NotificationService(); var viewModel = new MainViewModel(scanner, killer, settings, notifications, Dispatcher.CurrentDispatcher); await viewModel.InitializeAsync(); // Access observable collections ObservableCollection ports = viewModel.Ports; ObservableCollection filteredPorts = viewModel.FilteredPorts; // Kill a process await viewModel.KillProcessAsync(selectedPort); // Favorites management viewModel.ToggleFavorite(3000); bool isFavorite = viewModel.IsFavorite(3000); // Watched ports viewModel.AddWatchedPort(8080); viewModel.RemoveWatchedPort(8080); bool isWatched = viewModel.IsWatched(8080); // Search and filter viewModel.Search("node"); viewModel.ClearSearch(); viewModel.SelectedSidebarItem = SidebarItem.Favorites; ``` -------------------------------- ### App State Management (macOS) Source: https://context7.com/productdevbook/port-killer/llms.txt The AppState class manages the central application state for macOS applications using SwiftUI's @Observable macro. It handles ports, favorites, watched ports, filters, and Kubernetes/Cloudflare port forwarding, with automatic persistence via the Defaults library. ```swift // AppState - Central application state management import SwiftUI import Defaults @MainActor class MyAppController { let appState = AppState() func initialize() async { // Auto-starts scanning and refresh timer await appState.refresh() } // Access filtered ports based on sidebar selection var displayedPorts: [PortInfo] { appState.filteredPorts // Cached for performance } // Favorites management (persisted automatically) func manageFavorites() { appState.toggleFavorite(3000) let isFav = appState.isFavorite(3000) // true // Access all favorites let favorites = appState.favorites // Set } // Watched ports with notifications func watchPort() { appState.toggleWatch(8080) appState.updateWatch(8080, onStart: true, onStop: true) // Notifications fire automatically when port state changes } // Sidebar filtering func filterPorts() { appState.selectedSidebarItem = .favorites appState.selectedSidebarItem = .processType(.database) appState.filter.searchText = "node" } } ``` -------------------------------- ### PortInfo Data Model (Swift) Source: https://context7.com/productdevbook/port-killer/llms.txt Defines the PortInfo struct for representing network port and process information. It supports creating active port entries from scan results and inactive placeholders for tracking. The model is Identifiable, Hashable, and Sendable. ```swift // PortInfo - Port and process information model import Foundation // Create from scan results (done internally by PortScanner) let activePort = PortInfo.active( port: 3000, pid: 34805, processName: "node", address: "127.0.0.1", user: "developer", command: "/usr/local/bin/node server.js", fd: "19u" ) // Create inactive placeholder for favorites/watched let inactivePort = PortInfo.inactive(port: 8080) // Access properties print(activePort.displayPort) // ":3000" print(activePort.isActive) // true print(activePort.processType) // .development print(inactivePort.isActive) // false print(inactivePort.processName) // "Not running" // PortInfo is Identifiable, Hashable, and Sendable let portSet: Set = [activePort, inactivePort] ``` -------------------------------- ### Terminate Processes Gracefully (macOS - Swift) Source: https://context7.com/productdevbook/port-killer/llms.txt Provides methods for terminating processes on macOS. `killProcessGracefully` sends SIGTERM followed by SIGKILL if needed, while `killProcess` allows immediate forceful termination with SIGKILL. ```swift // Process Termination - Graceful kill with fallback let scanner = PortScanner() // Kill process gracefully (SIGTERM then SIGKILL after 500ms) let success = await scanner.killProcessGracefully(pid: 34805) if success { print("Process terminated successfully") } // Force kill immediately (SIGKILL) let forceSuccess = await scanner.killProcess(pid: 34805, force: true) // Via AppState for full integration @MainActor class AppController { let appState = AppState() func killPortProcess(_ portInfo: PortInfo) async { // Removes from UI immediately and refreshes await appState.killPort(portInfo) } func killAllProcesses() async { // Terminates all discovered port processes await appState.killAll() } } ``` -------------------------------- ### Scan Listening TCP Ports (Windows - C#) Source: https://context7.com/productdevbook/port-killer/llms.txt Scans listening TCP ports on Windows using the `PortScannerService`, leveraging Win32 `GetExtendedTcpTable` API for performance. It retrieves IPv4/IPv6 socket information and uses WMI for full command line details. ```csharp // PortScannerService Usage - Windows Win32 API scanning using PortKiller.Services; var scanner = new PortScannerService(); // Scan all listening TCP ports asynchronously var ports = await scanner.ScanPortsAsync(); foreach (var port in ports) { Console.WriteLine($"Port {port.Port}: {port.ProcessName} (PID: {port.Pid})"); Console.WriteLine($" Address: {port.Address}"); Console.WriteLine($" User: {port.User}"); Console.WriteLine($" Command: {port.Command}"); Console.WriteLine($" Type: {port.ProcessType}"); Console.WriteLine($" Active: {port.IsActive}"); } // Example output: // Port 8080: java (PID: 12345) // Address: 0.0.0.0 // User: DESKTOP\Developer // Command: C:\Program Files\Java\jdk-17\bin\java.exe -jar app.jar // Type: Development // Active: True ``` -------------------------------- ### Process Termination API (Windows) Source: https://context7.com/productdevbook/port-killer/llms.txt The ProcessKillerService handles process termination on Windows. It supports graceful shutdown using CloseMainWindow() with a timeout and immediate forced termination using Process.Kill(). It can also terminate all processes associated with a specific port and check for process existence. ```csharp // Process Termination - Windows implementation using PortKiller.Services; var killer = new ProcessKillerService(); // Kill process gracefully (CloseMainWindow + 500ms timeout + Kill) bool success = await killer.KillProcessGracefullyAsync(pid: 12345); // Force kill immediately bool forceSuccess = await killer.KillProcessAsync(pid: 12345, force: true); // Kill all processes on a specific port int killedCount = await killer.KillProcessesOnPortAsync(port: 8080); Console.WriteLine($"Killed {killedCount} processes on port 8080"); // Check if process exists bool exists = killer.ProcessExists(pid: 12345); ``` -------------------------------- ### Scan Listening TCP Ports (macOS - Swift) Source: https://context7.com/productdevbook/port-killer/llms.txt Uses the `PortScanner` actor to perform thread-safe port scanning on macOS. It executes `lsof` and parses output into `PortInfo` objects, including IPv4/IPv6, process details, and categorized types. ```swift // PortScanner Usage - Swift Actor for thread-safe port scanning import Foundation // Create scanner instance (actor ensures thread safety) let scanner = PortScanner() // Scan all listening TCP ports let ports = await scanner.scanPorts() // Each PortInfo contains detailed process information for port in ports { print("Port \(port.port): \(port.processName) (PID: \(port.pid))") print(" Address: \(port.address)") print(" User: \(port.user)") print(" Command: \(port.command)") print(" Type: \(port.processType.rawValue)") // Web Server, Database, Development, System, Other } // Example output: // Port 3000: node (PID: 34805) // Address: 127.0.0.1 // User: developer // Command: /usr/local/bin/node server.js // Type: Development ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.