diff --git a/install_python_stack.py b/studio/install_python_stack.py similarity index 98% rename from install_python_stack.py rename to studio/install_python_stack.py index 78ddc571d..927dc625b 100644 --- a/install_python_stack.py +++ b/studio/install_python_stack.py @@ -23,11 +23,11 @@ IS_WINDOWS = sys.platform == "win32" # ── Paths ────────────────────────────────────────────────────────────── SCRIPT_DIR = Path(__file__).resolve().parent -REQ_ROOT = SCRIPT_DIR / "studio" / "backend" / "requirements" +REQ_ROOT = SCRIPT_DIR / "backend" / "requirements" SINGLE_ENV = REQ_ROOT / "single-env" CONSTRAINTS = SINGLE_ENV / "constraints.txt" LOCAL_DD_UNSTRUCTURED_PLUGIN = ( - SCRIPT_DIR / "studio" / "backend" / "plugins" / "data-designer-unstructured-seed" + SCRIPT_DIR / "backend" / "plugins" / "data-designer-unstructured-seed" ) # ── Color support ────────────────────────────────────────────────────── diff --git a/setup.bat b/studio/setup.bat similarity index 100% rename from setup.bat rename to studio/setup.bat diff --git a/setup.ps1 b/studio/setup.ps1 similarity index 98% rename from setup.ps1 rename to studio/setup.ps1 index 5a573126a..6597fc674 100644 --- a/setup.ps1 +++ b/studio/setup.ps1 @@ -17,9 +17,9 @@ $ErrorActionPreference = "Stop" $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $PackageDir = Split-Path -Parent $ScriptDir -# Detect if running from pip install (no studio/frontend/ dir in repo) -$FrontendDir = Join-Path $ScriptDir "studio\frontend" -$OxcValidatorDir = Join-Path $ScriptDir "studio\backend\core\data_recipe\oxc-validator" +# Detect if running from pip install (no frontend/ dir in studio) +$FrontendDir = Join-Path $ScriptDir "frontend" +$OxcValidatorDir = Join-Path $ScriptDir "backend\core\data_recipe\oxc-validator" $IsPipInstall = -not (Test-Path $FrontendDir) # ───────────────────────────────────────────── @@ -587,7 +587,7 @@ if ($IsPipInstall) { Pop-Location $ErrorActionPreference = $prevEAP_npm Write-Host "[ERROR] npm install failed (exit code $LASTEXITCODE)" -ForegroundColor Red - Write-Host " Try running 'npm install' manually in studio/frontend/ to see errors" -ForegroundColor Yellow + Write-Host " Try running 'npm install' manually in frontend/ to see errors" -ForegroundColor Yellow exit 1 } npm run build 2>&1 | Out-Null @@ -599,7 +599,7 @@ if ($IsPipInstall) { } Pop-Location $ErrorActionPreference = $prevEAP_npm - Write-Host "[OK] Frontend built to studio/frontend/dist" -ForegroundColor Green + Write-Host "[OK] Frontend built to frontend/dist" -ForegroundColor Green } if (Test-Path $OxcValidatorDir) { @@ -648,8 +648,8 @@ if (-not $PythonCmd) { Write-Host "[OK] Using $PythonCmd ($(& $PythonCmd --version 2>&1))" -ForegroundColor Green # Always create a .venv for isolation -- even for pip installs. -# Created in the current working directory (where user ran the command). -$VenvDir = Join-Path (Get-Location) ".venv" +# Created in the repo root (parent of studio/). +$VenvDir = Join-Path (Split-Path -Parent $PSScriptRoot) ".venv" if (-not (Test-Path $VenvDir)) { Write-Host " Creating virtual environment at $VenvDir..." -ForegroundColor Cyan & $PythonCmd -m venv $VenvDir @@ -722,7 +722,7 @@ $ErrorActionPreference = $prevEAP # The training subprocess just prepends .venv_t5/ to sys.path — instant switch. Write-Host "" Write-Host " Pre-installing transformers 5.x for newer model support..." -ForegroundColor Cyan -$VenvT5Dir = Join-Path $PSScriptRoot ".venv_t5" +$VenvT5Dir = Join-Path (Split-Path -Parent $PSScriptRoot) ".venv_t5" if (Test-Path $VenvT5Dir) { Remove-Item -Recurse -Force $VenvT5Dir } New-Item -ItemType Directory -Path $VenvT5Dir -Force | Out-Null $prevEAP_t5 = $ErrorActionPreference @@ -956,10 +956,10 @@ if (Test-Path $LlamaServerBin) { # Add shell aliases (PowerShell profile + cmd batch files) # ============================================ Write-Host "" -$RepoDir = $PSScriptRoot +$RepoDir = Split-Path -Parent $PSScriptRoot $VenvPython = Join-Path $RepoDir ".venv\Scripts\python.exe" $CliScript = Join-Path $RepoDir "cli.py" -$FrontendDist = Join-Path $RepoDir "studio\frontend\dist" +$FrontendDist = Join-Path $PSScriptRoot "frontend\dist" $AliasAdded = $false # --- PowerShell profile: add functions --- diff --git a/setup.sh b/studio/setup.sh similarity index 93% rename from setup.sh rename to studio/setup.sh index 31a518d9c..31facb4b6 100755 --- a/setup.sh +++ b/studio/setup.sh @@ -5,6 +5,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # ── Helper: run command quietly, show output only on failure ── run_quiet() { @@ -28,9 +29,9 @@ echo "║ Unsloth Studio Setup Script ║" echo "╚══════════════════════════════════════╝" # ── Clean up stale Unsloth compiled caches ── -rm -rf "$SCRIPT_DIR/unsloth_compiled_cache" -rm -rf "$SCRIPT_DIR/studio/backend/unsloth_compiled_cache" -rm -rf "$SCRIPT_DIR/studio/tmp/unsloth_compiled_cache" +rm -rf "$REPO_ROOT/unsloth_compiled_cache" +rm -rf "$SCRIPT_DIR/backend/unsloth_compiled_cache" +rm -rf "$SCRIPT_DIR/tmp/unsloth_compiled_cache" # ── Detect Colab (like unsloth does) ── IS_COLAB=false @@ -99,13 +100,13 @@ echo "✅ Node $(node -v) | npm $(npm -v)" # ── 5. Build frontend ── echo "" echo "Building frontend..." -cd "$SCRIPT_DIR/studio/frontend" +cd "$SCRIPT_DIR/frontend" run_quiet "npm install" npm install run_quiet "npm run build" npm run build -cd "$SCRIPT_DIR/studio/backend/core/data_recipe/oxc-validator" +cd "$SCRIPT_DIR/backend/core/data_recipe/oxc-validator" run_quiet "npm install (oxc validator runtime)" npm install cd "$SCRIPT_DIR" -echo "✅ Frontend built to studio/frontend/dist" +echo "✅ Frontend built to frontend/dist" # ── 6. Python venv + deps ── echo "" @@ -168,7 +169,7 @@ fi BEST_VER=$("$BEST_PY" --version 2>&1 | awk '{print $2}') echo "✅ Using $BEST_PY ($BEST_VER) — compatible (3.${MIN_PY_MINOR}.x – 3.${MAX_PY_MINOR}.x)" -REQ_ROOT="$SCRIPT_DIR/studio/backend/requirements" +REQ_ROOT="$SCRIPT_DIR/backend/requirements" SINGLE_ENV_CONSTRAINTS="$REQ_ROOT/single-env/constraints.txt" SINGLE_ENV_DATA_DESIGNER="$REQ_ROOT/single-env/data-designer.txt" SINGLE_ENV_DATA_DESIGNER_DEPS="$REQ_ROOT/single-env/data-designer-deps.txt" @@ -183,11 +184,13 @@ if [ "$IS_COLAB" = true ]; then install_python_stack else # Local: create venv (always start fresh to preserve correct install order) + cd "$REPO_ROOT" rm -rf .venv rm -rf .venv_overlay # Remove legacy overlay (no longer used) rm -rf .venv_t5 # Will be rebuilt below "$BEST_PY" -m venv .venv source .venv/bin/activate + cd "$SCRIPT_DIR" install_python_stack # ── 6b. Pre-install transformers 5.x into .venv_t5/ ── @@ -196,7 +199,7 @@ else # The training subprocess just prepends .venv_t5/ to sys.path — instant switch. echo "" echo " Pre-installing transformers 5.x for newer model support..." - VENV_T5_DIR="$SCRIPT_DIR/.venv_t5" + VENV_T5_DIR="$REPO_ROOT/.venv_t5" mkdir -p "$VENV_T5_DIR" run_quiet "pip install transformers 5.x" pip install --target "$VENV_T5_DIR" --no-deps "transformers==5.2.0" run_quiet "pip install huggingface_hub for t5" pip install --target "$VENV_T5_DIR" --no-deps "huggingface_hub==1.3.0" @@ -318,32 +321,30 @@ LLAMA_SERVER_BIN="$LLAMA_CPP_DIR/build/bin/llama-server" # This alias hardcodes the venv python path so users don't need to activate. if [ "$IS_COLAB" = false ]; then echo "" -REPO_DIR="$SCRIPT_DIR" +REPO_DIR="$REPO_ROOT" # Detect the user's default shell and pick the right rc file USER_SHELL="$(basename "${SHELL:-/bin/bash}")" case "$USER_SHELL" in zsh) SHELL_RC="$HOME/.zshrc" - ALIAS_BLOCK="alias unsloth-studio='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist' -alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist'" + ALIAS_BLOCK="alias unsloth-studio='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist' +alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist'" ;; fish) SHELL_RC="$HOME/.config/fish/config.fish" - # fish uses 'abbr' or 'function'; a simple alias works via 'alias' in config.fish - ALIAS_BLOCK="alias unsloth-studio '${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist' -alias unsloth-ui '${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist'" + ALIAS_BLOCK="alias unsloth-studio '${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist' +alias unsloth-ui '${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist'" ;; ksh) SHELL_RC="$HOME/.kshrc" - ALIAS_BLOCK="alias unsloth-studio='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist' -alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist'" + ALIAS_BLOCK="alias unsloth-studio='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist' +alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist'" ;; *) - # Default to bash for bash and any other POSIX-compatible shell SHELL_RC="$HOME/.bashrc" - ALIAS_BLOCK="alias unsloth-studio='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist' -alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${REPO_DIR}/studio/frontend/dist'" + ALIAS_BLOCK="alias unsloth-studio='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist' +alias unsloth-ui='${REPO_DIR}/.venv/bin/python ${REPO_DIR}/cli.py studio -f ${SCRIPT_DIR}/frontend/dist'" ;; esac