( channelOrVersion: string, forceReinstall: boolean = false, )
| 974 | } |
| 975 | |
| 976 | async function installLatestImpl( |
| 977 | channelOrVersion: string, |
| 978 | forceReinstall: boolean = false, |
| 979 | ): Promise<InstallLatestResult> { |
| 980 | const updateResult = await updateLatest(channelOrVersion, forceReinstall) |
| 981 | |
| 982 | if (!updateResult.success) { |
| 983 | return { |
| 984 | latestVersion: null, |
| 985 | wasUpdated: false, |
| 986 | lockFailed: updateResult.lockFailed, |
| 987 | lockHolderPid: updateResult.lockHolderPid, |
| 988 | } |
| 989 | } |
| 990 | |
| 991 | // Installation succeeded (early return above covers failure). Mark as native |
| 992 | // and disable legacy auto-updater to protect symlinks. |
| 993 | const config = getGlobalConfig() |
| 994 | if (config.installMethod !== 'native') { |
| 995 | saveGlobalConfig(current => ({ |
| 996 | ...current, |
| 997 | installMethod: 'native', |
| 998 | // Disable legacy auto-updater to prevent npm sessions from deleting native symlinks. |
| 999 | // Native installations use NativeAutoUpdater instead, which respects native installation. |
| 1000 | autoUpdates: false, |
| 1001 | // Mark this as protection-based, not user preference |
| 1002 | autoUpdatesProtectedForNative: true, |
| 1003 | })) |
| 1004 | logForDebugging( |
| 1005 | 'Native installer: Set installMethod to "native" and disabled legacy auto-updater for protection', |
| 1006 | ) |
| 1007 | } |
| 1008 | |
| 1009 | void cleanupOldVersions() |
| 1010 | |
| 1011 | return { |
| 1012 | latestVersion: updateResult.latestVersion, |
| 1013 | wasUpdated: updateResult.success, |
| 1014 | lockFailed: false, |
| 1015 | } |
| 1016 | } |
| 1017 | |
| 1018 | async function getVersionFromSymlink( |
| 1019 | symlinkPath: string, |
no test coverage detected