diff --git a/install.ps1 b/install.ps1 index e56699327a..1ff57ae5c5 100644 --- a/install.ps1 +++ b/install.ps1 @@ -422,8 +422,17 @@ function Install-UnslothStudio { # the user re-exporting the env var. Default installs get an # empty string here so behavior matches today exactly. $studioHomeExport = if ($StudioRedirectMode -eq 'env') { + # Mirror setup.ps1: when an env override happens to equal the + # legacy default, llama.cpp still lives at ~/.unsloth/llama.cpp. + # Keep the persisted UNSLOTH_LLAMA_CPP_PATH consistent with that. + $_legacyStudio = Join-Path $env:USERPROFILE ".unsloth\studio" + $_llamaPath = if ($StudioHome -eq $_legacyStudio) { + Join-Path $env:USERPROFILE ".unsloth\llama.cpp" + } else { + Join-Path $StudioHome "llama.cpp" + } $_sq = $StudioHome -replace "'", "''" - $_llama = (Join-Path $StudioHome "llama.cpp") -replace "'", "''" + $_llama = $_llamaPath -replace "'", "''" "`$env:UNSLOTH_STUDIO_HOME = '$_sq'`n`$env:UNSLOTH_LLAMA_CPP_PATH = '$_llama'`n" } else { "" } diff --git a/install.sh b/install.sh index a25cea5747..74d6663941 100755 --- a/install.sh +++ b/install.sh @@ -611,8 +611,18 @@ LAUNCHER_EOF # custom-root build. Default installs do NOT get these lines so the # legacy ~/.unsloth/studio + ~/.unsloth/llama.cpp resolution stands. if [ "$_STUDIO_HOME_REDIRECT" = "env" ]; then + # Mirror setup.sh's legacy-equality check: when an env override + # happens to point at the legacy default, llama.cpp still lives + # at ~/.unsloth/llama.cpp (one shared build across legacy + # installs) -- keep UNSLOTH_LLAMA_CPP_PATH consistent with that. + _css_legacy_studio="$HOME/.unsloth/studio" + if [ "$STUDIO_HOME" = "$_css_legacy_studio" ]; then + _css_llama_path="$HOME/.unsloth/llama.cpp" + else + _css_llama_path="$STUDIO_HOME/llama.cpp" + fi _css_quoted_home=$(printf '%s' "$STUDIO_HOME" | sed "s/'/'\\\\''/g") - _css_quoted_llama=$(printf '%s' "$STUDIO_HOME/llama.cpp" | sed "s/'/'\\\\''/g") + _css_quoted_llama=$(printf '%s' "$_css_llama_path" | sed "s/'/'\\\\''/g") printf '%s\n' "export UNSLOTH_STUDIO_HOME='$_css_quoted_home'" printf '%s\n' "export UNSLOTH_LLAMA_CPP_PATH='$_css_quoted_llama'" fi diff --git a/studio/src-tauri/src/desktop_auth.rs b/studio/src-tauri/src/desktop_auth.rs index df09df7a14..72a29f4f0e 100644 --- a/studio/src-tauri/src/desktop_auth.rs +++ b/studio/src-tauri/src/desktop_auth.rs @@ -57,6 +57,10 @@ fn auth_secret_path(home: &Path, filename: &str) -> PathBuf { .join(filename) } +fn auth_secret_path_in_studio(studio: &Path, filename: &str) -> PathBuf { + studio.join("auth").join(filename) +} + fn auth_url(port: u16, route: &str) -> String { format!("http://127.0.0.1:{port}/api/auth/{route}") } @@ -65,7 +69,21 @@ fn home_dir() -> Result { dirs::home_dir().ok_or_else(|| "Could not determine home directory".to_string()) } +fn studio_root_from_env() -> Option { + for var in ["UNSLOTH_STUDIO_HOME", "STUDIO_HOME"] { + if let Some(value) = std::env::var_os(var) { + if !value.is_empty() { + return Some(PathBuf::from(value)); + } + } + } + None +} + fn desktop_secret_path() -> Result { + if let Some(studio) = studio_root_from_env() { + return Ok(auth_secret_path_in_studio(&studio, ".desktop_secret")); + } Ok(auth_secret_path(&home_dir()?, ".desktop_secret")) } @@ -308,6 +326,15 @@ mod tests { ); } + #[test] + fn auth_secret_path_in_studio_joins_under_custom_root() { + let studio = PathBuf::from("/srv/ws/studio"); + assert_eq!( + auth_secret_path_in_studio(&studio, ".desktop_secret"), + PathBuf::from("/srv/ws/studio/auth/.desktop_secret") + ); + } + #[test] fn auth_url_builds_local_endpoint() { assert_eq!( diff --git a/unsloth_cli/commands/studio.py b/unsloth_cli/commands/studio.py index 63986f8250..caf9050e19 100644 --- a/unsloth_cli/commands/studio.py +++ b/unsloth_cli/commands/studio.py @@ -67,7 +67,15 @@ STUDIO_HOME, _STUDIO_HOME_IS_CUSTOM = _resolve_studio_home() # correct build dir for GGUF export. if _STUDIO_HOME_IS_CUSTOM: os.environ.setdefault("UNSLOTH_STUDIO_HOME", str(STUDIO_HOME)) - os.environ.setdefault("UNSLOTH_LLAMA_CPP_PATH", str(STUDIO_HOME / "llama.cpp")) + # Mirror setup.sh / setup.ps1's legacy-equality check: when an env + # override happens to equal the legacy default, llama.cpp still lives + # at ~/.unsloth/llama.cpp (one shared build across legacy installs). + _legacy_studio = (Path.home() / ".unsloth" / "studio").resolve() + if STUDIO_HOME.resolve() == _legacy_studio: + _llama_dir = Path.home() / ".unsloth" / "llama.cpp" + else: + _llama_dir = STUDIO_HOME / "llama.cpp" + os.environ.setdefault("UNSLOTH_LLAMA_CPP_PATH", str(_llama_dir)) BOOTSTRAP_PASSWORD_FILE = ".bootstrap_password" DESKTOP_SECRET_FILE = ".desktop_secret" DEFAULT_ADMIN_USERNAME = "unsloth"