MCPcopy Index your code
hub / github.com/codeaashu/claude-code / checkInstall

Function checkInstall

src/utils/nativeInstaller/installer.ts:800–940  ·  view source on GitHub ↗
(
  force: boolean = false,
)

Source from the content-addressed store, hash-verified

798}
799
800export async function checkInstall(
801 force: boolean = false,
802): Promise<SetupMessage[]> {
803 // Skip all installation checks if disabled via environment variable
804 if (isEnvTruthy(process.env.DISABLE_INSTALLATION_CHECKS)) {
805 return []
806 }
807
808 // Get the actual installation type and config
809 const installationType = await getCurrentInstallationType()
810
811 // Skip checks for development builds - config.installMethod from a previous
812 // native installation shouldn't trigger warnings when running dev builds
813 if (installationType === 'development') {
814 return []
815 }
816
817 const config = getGlobalConfig()
818
819 // Only show warnings if:
820 // 1. User is actually running from native installation, OR
821 // 2. User has explicitly set installMethod to 'native' in config (they're trying to use native)
822 // 3. force is true (used during installation process)
823 const shouldCheckNative =
824 force || installationType === 'native' || config.installMethod === 'native'
825
826 if (!shouldCheckNative) {
827 return []
828 }
829
830 const dirs = getBaseDirectories()
831 const messages: SetupMessage[] = []
832 const localBinDir = dirname(dirs.executable)
833 const resolvedLocalBinPath = resolve(localBinDir)
834 const platform = getPlatform()
835 const isWindows = platform.startsWith('win32')
836
837 // Check if bin directory exists
838 try {
839 await access(localBinDir)
840 } catch {
841 messages.push({
842 message: `installMethod is native, but directory ${localBinDir} does not exist`,
843 userActionRequired: true,
844 type: 'error',
845 })
846 }
847
848 // Check if claude executable exists and is valid.
849 // On non-Windows, call readlink directly and route errno — ENOENT means
850 // the executable is missing, EINVAL means it exists but isn't a symlink.
851 // This avoids an access()→readlink() TOCTOU where deletion between the
852 // two calls produces a misleading "Not a symlink" diagnostic.
853 // isPossibleClaudeBinary stats the path internally, so we don't pre-check
854 // with access() — that would be a TOCTOU between access and the stat.
855 if (isWindows) {
856 // On Windows it's a copied executable, not a symlink
857 if (!(await isPossibleClaudeBinary(dirs.executable))) {

Callers 3

runFunction · 0.85
_temp2Function · 0.85

Calls 11

isEnvTruthyFunction · 0.85
getGlobalConfigFunction · 0.85
getBaseDirectoriesFunction · 0.85
getPlatformFunction · 0.85
isPossibleClaudeBinaryFunction · 0.85
isENOENTFunction · 0.85
getShellTypeFunction · 0.85
getShellConfigPathsFunction · 0.85
resolveFunction · 0.50
pushMethod · 0.45

Tested by

no test coverage detected