[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = tab\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.yml]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\non:\n  - push\n  - pull_request\njobs:\n  test:\n    name: Node.js ${{ matrix.node-version }} on ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version:\n          - 24\n          - 20\n        os:\n          - ubuntu-latest\n          - macos-latest\n          - windows-latest\n    steps:\n      - uses: actions/checkout@v5\n      - uses: actions/setup-node@v6\n        with:\n          node-version: ${{ matrix.node-version }}\n      - run: npm install\n      - run: npm test\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\nyarn.lock\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": "cli.js",
    "content": "#!/usr/bin/env node\nimport process from 'node:process';\nimport meow from 'meow';\nimport fkill from 'fkill';\n\nconst cli = meow(`\n\tUsage\n\t  $ fkill [<pid|name|:port> …]\n\n\tOptions\n\t  --force -f                         Force kill\n\t  --verbose -v                       Show process arguments\n\t  --silent -s                        Silently kill and always exit with code 0\n\t  --force-after-timeout <N>, -t <N>  Force kill processes which didn't exit after N seconds\n\t  --smart-case                       Case-insensitive unless pattern contains uppercase\n\t  --case-sensitive                   Force case-sensitive matching\n\n\tExamples\n\t  $ fkill 1337\n\t  $ fkill safari\n\t  $ fkill :8080\n\t  $ fkill 1337 safari :8080\n\t  $ fkill\n\n\tTo kill a port, prefix it with a colon. For example: :8080.\n\n\tRun without arguments to use the interactive mode.\n\tIn interactive mode, 🚦n% indicates high CPU usage and 🐏n% indicates high memory usage.\n\tSupports fuzzy search in the interactive mode.\n\n\tThe process name is case-insensitive by default.\n`, {\n\timportMeta: import.meta,\n\tinferType: true,\n\tflags: {\n\t\tforce: {\n\t\t\ttype: 'boolean',\n\t\t\tshortFlag: 'f',\n\t\t},\n\t\tverbose: {\n\t\t\ttype: 'boolean',\n\t\t\tshortFlag: 'v',\n\t\t},\n\t\tsilent: {\n\t\t\ttype: 'boolean',\n\t\t\tshortFlag: 's',\n\t\t},\n\t\tforceAfterTimeout: {\n\t\t\ttype: 'number',\n\t\t\tshortFlag: 't',\n\t\t},\n\t\tsmartCase: {\n\t\t\ttype: 'boolean',\n\t\t},\n\t\tcaseSensitive: {\n\t\t\ttype: 'boolean',\n\t\t},\n\t},\n});\n\nconst shouldIgnoreCase = (inputs, flags) => {\n\t// Explicit case-sensitive flag takes precedence over smart-case\n\tif (flags.caseSensitive) {\n\t\treturn false;\n\t}\n\n\t// Smart-case: ignore case unless ANY input contains uppercase\n\t// Note: With multiple inputs, if ANY has uppercase, ALL are matched case-sensitively\n\tif (flags.smartCase) {\n\t\tconst hasUpperCase = inputs.some(input => /[A-Z]/.test(String(input)));\n\t\treturn !hasUpperCase;\n\t}\n\n\t// Default: always ignore case (maintains backward compatibility)\n\treturn true;\n};\n\nif (cli.input.length === 0) {\n\tconst interactiveInterface = await import('./interactive.js');\n\tinteractiveInterface.init(cli.flags);\n} else {\n\tconst forceAfterTimeout = cli.flags.forceAfterTimeout === undefined ? undefined : cli.flags.forceAfterTimeout * 1000;\n\tconst ignoreCase = shouldIgnoreCase(cli.input, cli.flags);\n\tconst promise = fkill(cli.input, {...cli.flags, forceAfterTimeout, ignoreCase});\n\n\tif (!cli.flags.force) {\n\t\ttry {\n\t\t\tawait promise;\n\t\t} catch (error) {\n\t\t\tif (!cli.flags.silent) {\n\t\t\t\tif (error.message.includes('Could not find a process with port')) {\n\t\t\t\t\tconsole.error(error.message);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tconst interactiveInterface = await import('./interactive.js');\n\t\t\t\tinteractiveInterface.handleFkillError(cli.input, cli.flags);\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fixture.js",
    "content": "import process from 'node:process';\nimport http from 'node:http';\n\nconst server = http.createServer((request, response) => {\n\tresponse.end();\n});\n\nserver.listen(process.argv.slice(2)[0]);\n"
  },
  {
    "path": "interactive.js",
    "content": "import process from 'node:process';\nimport chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport search from '@inquirer/search';\nimport psList from 'ps-list';\nimport {numberSortDescending} from 'num-sort';\nimport escExit from 'esc-exit';\nimport cliTruncate from 'cli-truncate';\nimport {allPortsWithPid} from 'pid-port';\nimport fkill from 'fkill';\nimport {processExists} from 'process-exists';\nimport FuzzySearch from 'fuzzy-search';\n\nconst isWindows = process.platform === 'win32';\nconst commandLineMargins = 4;\n\nconst PROCESS_EXITED_MIN_INTERVAL = 5;\nconst PROCESS_EXITED_MAX_INTERVAL = 1280;\n\nconst delay = ms => new Promise(resolve => {\n\tsetTimeout(resolve, ms);\n});\n\nconst processExited = async (pid, timeout) => {\n\tconst endTime = Date.now() + timeout;\n\tlet interval = PROCESS_EXITED_MIN_INTERVAL;\n\tif (interval > timeout) {\n\t\tinterval = timeout;\n\t}\n\n\tlet exists;\n\n\tdo {\n\t\tawait delay(interval); // eslint-disable-line no-await-in-loop\n\n\t\texists = await processExists(pid); // eslint-disable-line no-await-in-loop\n\n\t\tinterval *= 2;\n\t\tif (interval > PROCESS_EXITED_MAX_INTERVAL) {\n\t\t\tinterval = PROCESS_EXITED_MAX_INTERVAL;\n\t\t}\n\t} while (Date.now() < endTime && exists);\n\n\treturn !exists;\n};\n\nconst preferNotMatching = matches => (a, b) => {\n\tconst aMatches = matches(a);\n\treturn matches(b) === aMatches ? 0 : (aMatches ? 1 : -1);\n};\n\nconst deprioritizedProcesses = new Set(['iTerm', 'iTerm2', 'fkill']);\nconst isDeprioritizedProcess = process_ => deprioritizedProcesses.has(process_.name);\nconst preferNotDeprioritized = preferNotMatching(isDeprioritizedProcess);\nconst preferLowAlphanumericNames = (a, b) => a.name.localeCompare(b.name);\n\nconst preferHighPerformanceImpact = (a, b) => {\n\tconst hasCpu = typeof a.cpu === 'number' && typeof b.cpu === 'number';\n\tconst hasMemory = typeof a.memory === 'number' && typeof b.memory === 'number';\n\n\tif (hasCpu && hasMemory) {\n\t\treturn numberSortDescending(a.cpu + a.memory, b.cpu + b.memory);\n\t}\n\n\tif (hasCpu) {\n\t\treturn numberSortDescending(a.cpu, b.cpu);\n\t}\n\n\tif (hasMemory) {\n\t\treturn numberSortDescending(a.memory, b.memory);\n\t}\n\n\treturn 0;\n};\n\nconst preferHeurisicallyInterestingProcesses = (a, b) => {\n\tlet result;\n\n\tresult = preferNotDeprioritized(a, b);\n\tif (result !== 0) {\n\t\treturn result;\n\t}\n\n\tresult = preferHighPerformanceImpact(a, b);\n\tif (result !== 0) {\n\t\treturn result;\n\t}\n\n\treturn preferLowAlphanumericNames(a, b);\n};\n\nconst isHelperProcess = process_ => process_.name.endsWith('-helper')\n\t|| process_.name.endsWith('Helper')\n\t|| process_.name.endsWith('HelperApp');\n\nconst renderPercentage = percents => {\n\tconst digits = Math.floor(percents * 10).toString().padStart(2, '0');\n\tconst whole = digits.slice(0, -1);\n\tconst fraction = digits.slice(-1);\n\treturn fraction === '0' ? `${whole}%` : `${whole}.${fraction}%`;\n};\n\nconst renderProcessForDisplay = (process_, flags, memoryThreshold, cpuThreshold) => {\n\tconst lineLength = process.stdout.columns || 80;\n\tconst ports = process_.ports.length === 0 ? '' : (' ' + process_.ports.slice(0, 4).map(x => `:${x}`).join(' '));\n\tconst memory = (process_.memory !== undefined && (process_.memory > memoryThreshold)) ? ` 🐏${renderPercentage(process_.memory)}` : '';\n\tconst cpu = (process_.cpu !== undefined && (process_.cpu > cpuThreshold)) ? `🚦${renderPercentage(process_.cpu)}` : '';\n\tconst margins = commandLineMargins + process_.pid.toString().length + ports.length + memory.length + cpu.length;\n\tconst length = lineLength - margins;\n\tconst name = cliTruncate(flags.verbose && !isWindows ? process_.cmd : process_.name, length, {position: 'middle', preferTruncationOnSpace: true});\n\tconst extraMargin = 2;\n\tconst spacer = lineLength === process.stdout.columns ? ''.padEnd(length - name.length - extraMargin) : '';\n\n\treturn {\n\t\tname: `${name} ${chalk.dim(process_.pid)}${spacer}${chalk.dim(ports)}${cpu}${memory}`,\n\t\tvalue: process_.pid,\n\t};\n};\n\nconst searchProcessesByPort = (processes, port) => processes.filter(process_ => process_.ports.includes(port));\n\nconst searchProcessByPid = (processes, pid) => processes.find(process_ => String(process_.pid) === pid);\n\nconst searchProcessesByName = (processes, term, searcher, flags = {}) => {\n\t// Determine if we should match case-sensitively\n\tconst hasUpperCase = /[A-Z]/.test(term);\n\tconst shouldMatchCase = flags.caseSensitive || (flags.smartCase && hasUpperCase);\n\n\tconst normalizedTerm = shouldMatchCase ? term : term.toLowerCase();\n\tconst exactMatches = [];\n\tconst startsWithMatches = [];\n\tconst containsMatches = [];\n\n\tfor (const process_ of processes) {\n\t\tconst normalizedName = shouldMatchCase ? process_.name : process_.name.toLowerCase();\n\t\tif (normalizedName === normalizedTerm) {\n\t\t\texactMatches.push(process_);\n\t\t} else if (normalizedName.startsWith(normalizedTerm)) {\n\t\t\tstartsWithMatches.push(process_);\n\t\t} else if (normalizedName.includes(normalizedTerm)) {\n\t\t\tcontainsMatches.push(process_);\n\t\t}\n\t}\n\n\t// Fuzzy matches (excluding all exact/starts/contains matches)\n\t// Keep fuzzy search case-insensitive for better UX\n\tconst matchedPids = new Set([...exactMatches, ...startsWithMatches, ...containsMatches].map(process_ => process_.pid));\n\tconst fuzzyResults = searcher.search(term).filter(process_ => !matchedPids.has(process_.pid));\n\n\t// Combine in priority order\n\treturn [...exactMatches, ...startsWithMatches, ...containsMatches, ...fuzzyResults];\n};\n\nconst filterAndSortProcesses = (processes, term, searcher, flags) => {\n\tconst filtered = processes.filter(process_ => !isHelperProcess(process_));\n\n\t// No search term: show all sorted by performance\n\tif (!term) {\n\t\treturn filtered.sort(preferHeurisicallyInterestingProcesses);\n\t}\n\n\t// Search by port\n\tif (term.startsWith(':')) {\n\t\tconst port = term.slice(1);\n\t\treturn searchProcessesByPort(filtered, port);\n\t}\n\n\t// Search by PID\n\tconst pidMatch = searchProcessByPid(filtered, term);\n\tif (pidMatch) {\n\t\treturn [pidMatch];\n\t}\n\n\t// Search by name\n\treturn searchProcessesByName(filtered, term, searcher, flags);\n};\n\nconst handleFkillError = async (inputs, flags = {}) => {\n\tconst shouldForceKill = await promptForceKill(inputs, 'Error killing process.');\n\n\tif (shouldForceKill) {\n\t\t// Determine case sensitivity based on flags and inputs\n\t\t// If ANY input has uppercase letter, match case-sensitively with --smart-case\n\t\tconst hasUpperCase = inputs.some(input => /[A-Z]/.test(String(input)));\n\t\tconst ignoreCase = flags.caseSensitive ? false : (flags.smartCase ? !hasUpperCase : true);\n\n\t\tawait fkill(inputs, {\n\t\t\tforce: true,\n\t\t\tignoreCase,\n\t\t});\n\t}\n};\n\nconst DEFAULT_EXIT_TIMEOUT = 3000;\n\nconst attemptKillProcesses = async processes => {\n\ttry {\n\t\tawait fkill(processes);\n\t\tconst exitStatuses = await Promise.all(processes.map(process_ => processExited(process_, DEFAULT_EXIT_TIMEOUT)));\n\t\tconst survivors = processes.filter((_, index) => !exitStatuses[index]);\n\t\treturn {survivors, hadError: false};\n\t} catch {\n\t\treturn {survivors: processes, hadError: true};\n\t}\n};\n\nconst promptForceKill = async (survivingProcesses, message) => {\n\tif (process.stdout.isTTY === false) {\n\t\tconsole.error(`${message} Try \\`fkill --force ${survivingProcesses.join(' ')}\\``);\n\t\tprocess.exit(1); // eslint-disable-line unicorn/no-process-exit\n\t}\n\n\tconst answer = await inquirer.prompt([{\n\t\ttype: 'confirm',\n\t\tname: 'forceKill',\n\t\tmessage: `${message} Would you like to use the force?`,\n\t}]);\n\n\treturn answer.forceKill;\n};\n\nconst performKillSequence = async processes => {\n\tconst processList = Array.isArray(processes) ? processes : [processes];\n\tconst {survivors, hadError} = await attemptKillProcesses(processList);\n\n\tif (survivors.length === 0) {\n\t\treturn;\n\t}\n\n\tconst suffix = survivors.length > 1 ? 'es' : '';\n\tconst message = hadError ? `Error killing process${suffix}.` : `Process${suffix} didn't exit in ${DEFAULT_EXIT_TIMEOUT}ms.`;\n\tconst shouldForceKill = await promptForceKill(survivors, message);\n\n\tif (shouldForceKill) {\n\t\tawait fkill(processList, {\n\t\t\tforce: true,\n\t\t\tignoreCase: true,\n\t\t});\n\t}\n};\n\nconst findPortsForProcess = (processId, portToPidMap) => {\n\tconst ports = [];\n\n\tfor (const [port, pid] of portToPidMap.entries()) {\n\t\tif (processId === pid) {\n\t\t\tports.push(String(port));\n\t\t}\n\t}\n\n\treturn ports;\n};\n\nconst listProcesses = async (processes, flags) => {\n\tconst memoryThreshold = flags.verbose ? 0 : 1;\n\tconst cpuThreshold = flags.verbose ? 0 : 3;\n\tconst searcher = new FuzzySearch(processes, ['name'], {caseSensitive: false});\n\n\tconst selectedPid = await search({\n\t\tmessage: 'Running processes:',\n\t\tpageSize: 10,\n\t\tasync source(term = '') {\n\t\t\tconst matchingProcesses = filterAndSortProcesses(processes, term, searcher, flags);\n\t\t\treturn matchingProcesses.map(process_ => renderProcessForDisplay(process_, flags, memoryThreshold, cpuThreshold));\n\t\t},\n\t});\n\n\tperformKillSequence(selectedPid);\n};\n\nconst init = async flags => {\n\tescExit();\n\n\tconst [portToPidMap, processes] = await Promise.all([\n\t\tallPortsWithPid(),\n\t\tpsList({all: false}),\n\t]);\n\n\tconst processesWithPorts = processes.map(process_ => ({\n\t\t...process_,\n\t\tports: findPortsForProcess(process_.pid, portToPidMap),\n\t}));\n\n\tlistProcesses(processesWithPorts, flags);\n};\n\nexport {init, handleFkillError};\n"
  },
  {
    "path": "license",
    "content": "MIT License\n\nCopyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"name\": \"fkill-cli\",\n\t\"version\": \"9.0.0\",\n\t\"description\": \"Fabulously kill processes. Cross-platform.\",\n\t\"license\": \"MIT\",\n\t\"repository\": \"sindresorhus/fkill-cli\",\n\t\"funding\": \"https://github.com/sponsors/sindresorhus\",\n\t\"author\": {\n\t\t\"name\": \"Sindre Sorhus\",\n\t\t\"email\": \"sindresorhus@gmail.com\",\n\t\t\"url\": \"https://sindresorhus.com\"\n\t},\n\t\"type\": \"module\",\n\t\"bin\": {\n\t\t\"fkill\": \"./cli.js\"\n\t},\n\t\"sideEffects\": false,\n\t\"engines\": {\n\t\t\"node\": \">=20\"\n\t},\n\t\"scripts\": {\n\t\t\"test\": \"xo && ava\"\n\t},\n\t\"files\": [\n\t\t\"cli.js\",\n\t\t\"interactive.js\"\n\t],\n\t\"keywords\": [\n\t\t\"cli-app\",\n\t\t\"cli\",\n\t\t\"fkill\",\n\t\t\"kill\",\n\t\t\"killing\",\n\t\t\"killall\",\n\t\t\"taskkill\",\n\t\t\"sigkill\",\n\t\t\"sigterm\",\n\t\t\"force\",\n\t\t\"exit\",\n\t\t\"zap\",\n\t\t\"die\",\n\t\t\"ps\",\n\t\t\"proc\"\n\t],\n\t\"dependencies\": {\n\t\t\"@inquirer/search\": \"^3.2.1\",\n\t\t\"chalk\": \"^5.6.2\",\n\t\t\"cli-truncate\": \"^5.1.1\",\n\t\t\"esc-exit\": \"^3.0.1\",\n\t\t\"fkill\": \"^10.0.0\",\n\t\t\"fuzzy-search\": \"^3.2.1\",\n\t\t\"inquirer\": \"^12.11.0\",\n\t\t\"meow\": \"^14.0.0\",\n\t\t\"num-sort\": \"^4.0.0\",\n\t\t\"pid-port\": \"^2.0.0\",\n\t\t\"ps-list\": \"^9.0.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"ava\": \"^6.4.1\",\n\t\t\"delay\": \"^7.0.0\",\n\t\t\"execa\": \"^9.6.0\",\n\t\t\"get-port\": \"^7.1.0\",\n\t\t\"noop-process\": \"^5.0.0\",\n\t\t\"process-exists\": \"^5.0.0\",\n\t\t\"xo\": \"^1.2.3\"\n\t}\n}\n"
  },
  {
    "path": "readme.md",
    "content": "<h1 align=\"center\">\n\t<br>\n\t<img width=\"360\" src=\"https://cdn.jsdelivr.net/gh/sindresorhus/fkill@913dce9ae670cd12410f6a64eaf94d7e5f50ed69/media/logo.svg\" alt=\"fkill\">\n\t<br>\n\t<br>\n\t<br>\n</h1>\n\n> Fabulously kill processes. Cross-platform.\n\nWorks on macOS, Linux, and Windows.\n\n## Install\n\n```sh\nnpm install --global fkill-cli\n```\n\n## Usage\n\n```\n$ fkill --help\n\n\tUsage\n\t\t$ fkill [<pid|name|:port> …]\n\n\tOptions\n\t\t--force, -f                  Force kill\n\t\t--verbose, -v                Show process arguments\n\t\t--silent, -s                 Silently kill and always exit with code 0\n\t\t--force-timeout <N>, -t <N>  Force kill processes which didn't exit after N seconds\n\t\t--smart-case                 Case-insensitive unless pattern contains uppercase\n\t\t--case-sensitive             Force case-sensitive matching\n\n\tExamples\n\t\t$ fkill 1337\n\t\t$ fkill safari\n\t\t$ fkill :8080\n\t\t$ fkill 1337 safari :8080\n\t\t$ fkill\n\n\tTo kill a port, prefix it with a colon. For example: :8080.\n\n\tRun without arguments to use the interactive interface.\n\tIn interactive mode, 🚦n% indicates high CPU usage and 🐏n% indicates high memory usage.\n\tSupports fuzzy search in the interactive mode.\n\n\tThe process name is case-insensitive by default.\n```\n\n## Interactive UI\n\nRun `fkill` without arguments to launch the interactive UI.\n\n![](screenshot.svg)\n\n## Related\n\n- [fkill](https://github.com/sindresorhus/fkill) - API for this package\n- [alfred-fkill](https://github.com/SamVerschueren/alfred-fkill) - Alfred workflow for this package\n"
  },
  {
    "path": "test.js",
    "content": "import process from 'node:process';\nimport childProcess from 'node:child_process';\nimport test from 'ava';\nimport {execa} from 'execa';\nimport delay from 'delay';\nimport noopProcess from 'noop-process';\nimport {processExists} from 'process-exists';\nimport getPort from 'get-port';\n\nconst noopProcessKilled = async (t, pid) => {\n\t// Ensure the noop process has time to exit\n\tawait delay(100);\n\tt.false(await processExists(pid));\n};\n\ntest('main', async t => {\n\tconst {stdout} = await execa('./cli.js', ['--version']);\n\tt.true(stdout.length > 0);\n});\n\ntest('pid', async t => {\n\tconst pid = await noopProcess();\n\tawait execa('./cli.js', ['--force', pid]);\n\tawait noopProcessKilled(t, pid);\n});\n\n// TODO: Upgrading AVA to latest caused this to not finish. Unclear why.\n// test('fuzzy search', async t => {\n// \tconst pid = await noopProcess({title: '!noo00oop@'});\n// \tawait execa('./cli.js', ['o00oop@']);\n// \tawait noopProcessKilled(t, pid);\n// });\n\ntest('kill from port', async t => {\n\tconst port = await getPort();\n\tconst {pid} = childProcess.spawn('node', ['fixture.js', port]);\n\tawait execa('./cli.js', ['--force', pid]);\n\tawait noopProcessKilled(t, pid);\n});\n\ntest('error when process is not found', async t => {\n\tawait t.throwsAsync(\n\t\texeca('./cli.js', ['--force', 'notFoundProcess']),\n\t\t{message: /Killing process notFoundProcess failed: Process doesn't exist/},\n\t);\n});\n\ntest('force killing process at unused port throws error', async t => {\n\tawait t.throwsAsync(\n\t\texeca('./cli.js', ['--force', ':1337']),\n\t\t{message: /Killing process :1337 failed: Process doesn't exist/},\n\t);\n});\n\ntest('silently force killing process at unused port exits with code 0', async t => {\n\tconst {exitCode} = await execa('./cli.js', ['--force', '--silent', ':1337']);\n\tt.is(exitCode, 0);\n});\n\n// Case-sensitivity tests only work on Unix-like systems\n// Windows process names work differently and don't support custom titles via noopProcess\nif (process.platform !== 'win32') {\n\ttest('default case-insensitive behavior', async t => {\n\t\tconst pid = await noopProcess({title: 'DefaultCase'});\n\t\tawait execa('./cli.js', ['--force', 'defaultcase']);\n\t\tawait noopProcessKilled(t, pid);\n\t});\n\n\ttest('case-sensitive flag makes matching case-sensitive', async t => {\n\t\tconst pid = await noopProcess({title: 'CaseSensitive'});\n\t\tawait t.throwsAsync(\n\t\t\texeca('./cli.js', ['--case-sensitive', '--force', 'casesensitive']),\n\t\t\t{message: /Killing process casesensitive failed/},\n\t\t);\n\t\t// Clean up the process\n\t\tawait execa('./cli.js', ['--force', pid]);\n\t});\n\n\ttest('smart-case with lowercase is case-insensitive', async t => {\n\t\tconst pid = await noopProcess({title: 'SmartLower'});\n\t\tawait execa('./cli.js', ['--smart-case', '--force', 'smartlower']);\n\t\tawait noopProcessKilled(t, pid);\n\t});\n\n\ttest('smart-case with uppercase is case-sensitive', async t => {\n\t\tconst pid = await noopProcess({title: 'smartupper'});\n\t\tawait t.throwsAsync(\n\t\t\texeca('./cli.js', ['--smart-case', '--force', 'SmartUpper']),\n\t\t\t{message: /Killing process SmartUpper failed/},\n\t\t);\n\t\t// Clean up the process\n\t\tawait execa('./cli.js', ['--force', pid]);\n\t});\n}\n\ntest('silent flag with -s shortflag works', async t => {\n\tconst {exitCode} = await execa('./cli.js', ['-s', '--force', ':1337']);\n\tt.is(exitCode, 0);\n});\n"
  }
]