MCPcopy Create free account
hub / github.com/Noumena-Network/code / detectIDEs

Function detectIDEs

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

Source from the content-addressed store, hash-verified

689 * the workspace directory does not match the cwd)
690 */
691export async function detectIDEs(
692 includeInvalid: boolean,
693): Promise<DetectedIDEInfo[]> {
694 const detectedIDEs: DetectedIDEInfo[] = []
695 const singleLiveWorkspaceMismatchFallbacks: DetectedIDEInfo[] = []
696
697 try {
698 // Get the CLAUDE_CODE_SSE_PORT if set
699 const ssePort = process.env.CLAUDE_CODE_SSE_PORT
700 const envPort = ssePort ? parseInt(ssePort) : null
701
702 // Get the current working directory, normalized to NFC for consistent
703 // comparison. macOS returns NFD paths (decomposed Unicode), while IDEs
704 // like VS Code report NFC paths (composed Unicode). Without normalization,
705 // paths containing accented/CJK characters fail to match.
706 const cwd = getOriginalCwd().normalize('NFC')
707
708 // Get sorted lockfiles (full paths) and read them all in parallel.
709 // findAvailableIDE() polls this every 1s for up to 30s; serial I/O here was
710 // showing up as ~500ms self-time in CPU profiles.
711 const lockfiles = await getSortedIdeLockfiles()
712 const lockfileInfos = await Promise.all(lockfiles.map(readIdeLockfile))
713
714 // Ancestor PID walk shells out (ps in a loop, up to 10x). Make it lazy and
715 // single-shot per detectIDEs() call; with the workspace-check-first ordering
716 // below, this often never fires at all.
717 const getAncestors = makeAncestorPidLookup()
718 const needsAncestryCheck = getPlatform() !== 'wsl' && isSupportedTerminal()
719
720 // Try to find a lockfile that contains our current working directory
721 for (const lockfileInfo of lockfileInfos) {
722 if (!lockfileInfo) continue
723
724 let isValid = false
725 const skipValidityCheck = isEnvTruthy(
726 process.env.CLAUDE_CODE_IDE_SKIP_VALID_CHECK,
727 )
728 if (isEnvTruthy(process.env.CLAUDE_CODE_IDE_SKIP_VALID_CHECK)) {
729 isValid = true
730 } else if (lockfileInfo.port === envPort) {
731 // If the port matches the environment variable, mark as valid regardless of directory
732 isValid = true
733 } else {
734 // Otherwise, check if the current working directory is within the workspace folders
735 isValid = lockfileInfo.workspaceFolders.some(idePath => {
736 if (!idePath) return false
737
738 let localPath = idePath
739
740 // Handle WSL-specific path conversion and distro matching
741 if (
742 getPlatform() === 'wsl' &&
743 lockfileInfo.runningInWindows &&
744 process.env.WSL_DISTRO_NAME
745 ) {
746 // Check for WSL distro mismatch
747 if (!checkWSLDistroMatch(idePath, process.env.WSL_DISTRO_NAME)) {
748 return false

Callers 4

ide.test.tsFile · 0.85
findAvailableIDEFunction · 0.85
callFunction · 0.85
_temp2Function · 0.85

Calls 13

toLocalPathMethod · 0.95
isEnvTruthyFunction · 0.90
getOriginalCwdFunction · 0.85
getSortedIdeLockfilesFunction · 0.85
makeAncestorPidLookupFunction · 0.85
getPlatformFunction · 0.85
checkWSLDistroMatchFunction · 0.85
toIDEDisplayNameFunction · 0.85
checkIdeConnectionFunction · 0.85
resolveFunction · 0.70
isProcessRunningFunction · 0.70
logErrorFunction · 0.70

Tested by

no test coverage detected