MCPcopy
hub / github.com/codeaashu/claude-code / detectIDEs

Function detectIDEs

src/utils/ide.ts:664–827  ·  view source on GitHub ↗
(
  includeInvalid: boolean,
)

Source from the content-addressed store, hash-verified

662 * the workspace directory does not match the cwd)
663 */
664export async function detectIDEs(
665 includeInvalid: boolean,
666): Promise<DetectedIDEInfo[]> {
667 const detectedIDEs: DetectedIDEInfo[] = []
668
669 try {
670 // Get the CLAUDE_CODE_SSE_PORT if set
671 const ssePort = process.env.CLAUDE_CODE_SSE_PORT
672 const envPort = ssePort ? parseInt(ssePort) : null
673
674 // Get the current working directory, normalized to NFC for consistent
675 // comparison. macOS returns NFD paths (decomposed Unicode), while IDEs
676 // like VS Code report NFC paths (composed Unicode). Without normalization,
677 // paths containing accented/CJK characters fail to match.
678 const cwd = getOriginalCwd().normalize('NFC')
679
680 // Get sorted lockfiles (full paths) and read them all in parallel.
681 // findAvailableIDE() polls this every 1s for up to 30s; serial I/O here was
682 // showing up as ~500ms self-time in CPU profiles.
683 const lockfiles = await getSortedIdeLockfiles()
684 const lockfileInfos = await Promise.all(lockfiles.map(readIdeLockfile))
685
686 // Ancestor PID walk shells out (ps in a loop, up to 10x). Make it lazy and
687 // single-shot per detectIDEs() call; with the workspace-check-first ordering
688 // below, this often never fires at all.
689 const getAncestors = makeAncestorPidLookup()
690 const needsAncestryCheck = getPlatform() !== 'wsl' && isSupportedTerminal()
691
692 // Try to find a lockfile that contains our current working directory
693 for (const lockfileInfo of lockfileInfos) {
694 if (!lockfileInfo) continue
695
696 let isValid = false
697 if (isEnvTruthy(process.env.CLAUDE_CODE_IDE_SKIP_VALID_CHECK)) {
698 isValid = true
699 } else if (lockfileInfo.port === envPort) {
700 // If the port matches the environment variable, mark as valid regardless of directory
701 isValid = true
702 } else {
703 // Otherwise, check if the current working directory is within the workspace folders
704 isValid = lockfileInfo.workspaceFolders.some(idePath => {
705 if (!idePath) return false
706
707 let localPath = idePath
708
709 // Handle WSL-specific path conversion and distro matching
710 if (
711 getPlatform() === 'wsl' &&
712 lockfileInfo.runningInWindows &&
713 process.env.WSL_DISTRO_NAME
714 ) {
715 // Check for WSL distro mismatch
716 if (!checkWSLDistroMatch(idePath, process.env.WSL_DISTRO_NAME)) {
717 return false
718 }
719
720 // Try both the original path and the converted path
721 // This handles cases where the IDE might report either format

Callers 3

findAvailableIDEFunction · 0.85
callFunction · 0.85
_temp2Function · 0.85

Calls 13

toLocalPathMethod · 0.95
getOriginalCwdFunction · 0.85
getSortedIdeLockfilesFunction · 0.85
makeAncestorPidLookupFunction · 0.85
getPlatformFunction · 0.85
isEnvTruthyFunction · 0.85
checkWSLDistroMatchFunction · 0.85
toIDEDisplayNameFunction · 0.85
resolveFunction · 0.70
isProcessRunningFunction · 0.70
logErrorFunction · 0.70
hasMethod · 0.45

Tested by

no test coverage detected