From 6b0b10133192be170db8d8646a8f7092b4aae630 Mon Sep 17 00:00:00 2001 From: Schultz Lab at NCCU Date: Tue, 21 Jul 2026 18:20:34 -0400 Subject: [PATCH 1/4] Enhance launcher scripts for conda detection and add Linux support --- README.md | 27 +++++++-- launch-native-jupyter.sh | 25 ++++++++- launch-native.bat | 2 +- launch-native.command | 17 ++++-- launch-native.sh | 118 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 10 deletions(-) mode change 100755 => 100644 launch-native.command create mode 100644 launch-native.sh diff --git a/README.md b/README.md index 20d9bb0..bd5b4cc 100644 --- a/README.md +++ b/README.md @@ -195,10 +195,29 @@ no rebuild. | Platform | File | Action | | --- | --- | --- | | Windows | [`launch-native.bat`](launch-native.bat) | Activates the `quantui` conda env inside WSL Ubuntu, runs Voilà, and opens `http://localhost:8867` | -| macOS / Linux | [`launch-native.command`](launch-native.command) | Activates the local `quantui` conda env directly (no WSL needed) and does the same | - -Both launchers reuse port `8867`, so you can keep the same browser tab pinned -across platforms. +| macOS | [`launch-native.command`](launch-native.command) | Activates the local `quantui` conda env directly (no WSL needed) and does the same | +| Linux / WSL | [`launch-native.sh`](launch-native.sh) | Run `./launch-native.sh` from a Linux or WSL terminal; activates `quantui` and does the same | + +All launchers reuse port `8867`, so you can keep the same browser tab pinned +across platforms. They **auto-detect your conda installation** — miniforge +(recommended), miniconda, or anaconda, in your home directory or a system +prefix — so no path editing is needed regardless of which you installed. + +> **WSL users — clone into the Linux filesystem, not `/mnt/c`.** Running +> `pip install -e .` (or the launchers) against a repo on the Windows drive +> (`/mnt/c/...`) fails with `error: [Errno 1] Operation not permitted` because +> the 9P bridge WSL uses for Windows files doesn't support the file operations +> an editable build needs — and it's ~10× slower besides. Clone the repo into +> your WSL home instead and work from there: +> +> ```bash +> git clone https://github.com/The-Schultz-Lab/QuantUI.git ~/GitHub/QuantUI +> cd ~/GitHub/QuantUI +> ``` +> +> Then open it in VS Code with `code .` (installs the WSL server and reopens +> the window connected to WSL). `launch-native.sh` resolves its own location, +> so it works from any clone path. ### Windows — pin to the Start menu diff --git a/launch-native-jupyter.sh b/launch-native-jupyter.sh index c5cf9e4..02c32ef 100644 --- a/launch-native-jupyter.sh +++ b/launch-native-jupyter.sh @@ -12,7 +12,30 @@ mkdir -p "$(dirname "$LOG_FILE")" exec > >(tee -a "$LOG_FILE") 2>&1 -source ~/miniconda3/etc/profile.d/conda.sh +# Locate conda.sh. Detect the install rather than assuming one location: +# miniforge (recommended for WSL), miniconda, and anaconda are all supported. +# Falls back to an already-configured conda via $CONDA_EXE. +CONDA_SH="" +for candidate in \ + "$HOME/miniforge3/etc/profile.d/conda.sh" \ + "$HOME/miniconda3/etc/profile.d/conda.sh" \ + "$HOME/anaconda3/etc/profile.d/conda.sh" \ + "/opt/miniforge3/etc/profile.d/conda.sh" \ + "/opt/miniconda3/etc/profile.d/conda.sh" \ + "/opt/conda/etc/profile.d/conda.sh"; do + [ -f "$candidate" ] && CONDA_SH="$candidate" && break +done +if [ -z "$CONDA_SH" ] && [ -n "${CONDA_EXE:-}" ]; then + fallback="$(dirname "$(dirname "$CONDA_EXE")")/etc/profile.d/conda.sh" + [ -f "$fallback" ] && CONDA_SH="$fallback" +fi +if [ -z "$CONDA_SH" ]; then + echo "ERROR: Could not locate conda.sh. Install Miniforge to ~/miniforge3." + echo " https://github.com/conda-forge/miniforge" + exit 1 +fi +# shellcheck disable=SC1090 +source "$CONDA_SH" conda activate quantui echo "Using Python: $(command -v python)" diff --git a/launch-native.bat b/launch-native.bat index f8173a1..78db1f2 100644 --- a/launch-native.bat +++ b/launch-native.bat @@ -25,7 +25,7 @@ REM make EVERY subsequent offline launch retry (and re-delay on) pip — the REM reinstall is attempted once, then skipped. quantui/*.py + package-data are REM live in editable mode, so a skipped reinstall is harmless offline; re-run REM `pip install -e .` manually when online if you add a real dependency. -start "QuantUI [native]" wsl -d Ubuntu -- bash -c "cd '%WSLPATH%' && source ~/miniconda3/etc/profile.d/conda.sh && conda activate quantui && if [ pyproject.toml -nt .dev_install_stamp ] || ! python -c 'import quantui' 2>/dev/null; then pip install -e . -q --timeout=5 --retries=0 && touch .dev_install_stamp || { echo '[QuantUI] editable reinstall skipped (offline?) - using live source'; touch .dev_install_stamp; }; fi; rm -rf quantui/__pycache__ && PYTHONDONTWRITEBYTECODE=1 voila notebooks/molecule_computations.ipynb --no-browser --port=8867 --ServerApp.disable_check_xsrf=True" +start "QuantUI [native]" wsl -d Ubuntu -- bash -c "cd '%WSLPATH%' && for c in ~/miniforge3 ~/miniconda3 ~/anaconda3 /opt/conda; do [ -f $c/etc/profile.d/conda.sh ] && . $c/etc/profile.d/conda.sh && break; done && conda activate quantui && if [ pyproject.toml -nt .dev_install_stamp ] || ! python -c 'import quantui' 2>/dev/null; then pip install -e . -q --timeout=5 --retries=0 && touch .dev_install_stamp || { echo '[QuantUI] editable reinstall skipped (offline?) - using live source'; touch .dev_install_stamp; }; fi; rm -rf quantui/__pycache__ && PYTHONDONTWRITEBYTECODE=1 voila notebooks/molecule_computations.ipynb --no-browser --port=8867 --ServerApp.disable_check_xsrf=True" echo Waiting for Voila to start... timeout /t 6 /nobreak > nul diff --git a/launch-native.command b/launch-native.command old mode 100755 new mode 100644 index 5000abb..1f1593a --- a/launch-native.command +++ b/launch-native.command @@ -17,10 +17,15 @@ echo "QuantUI NATIVE MODE — Local conda env on macOS, no container" echo "Use this when you have edited quantui/*.py and want to test immediately." echo -# Locate conda.sh. Miniconda at ~/miniconda3 is the documented install; -# we try a few common fallback locations before giving up. +# Locate conda.sh. Detect the install rather than assuming one location: +# miniforge, miniconda, and anaconda are all supported, in home, /opt, and +# Homebrew Caskroom prefixes. Falls back to an already-configured conda via +# $CONDA_EXE. CONDA_SH="" for candidate in \ + "$HOME/miniforge3/etc/profile.d/conda.sh" \ + "/opt/miniforge3/etc/profile.d/conda.sh" \ + "/opt/homebrew/Caskroom/miniforge/base/etc/profile.d/conda.sh" \ "/opt/miniconda3/etc/profile.d/conda.sh" \ "/opt/miniconda3/condabin/conda" \ "$HOME/miniconda3/etc/profile.d/conda.sh" \ @@ -34,11 +39,15 @@ for candidate in \ break fi done +if [ -z "$CONDA_SH" ] && [ -n "${CONDA_EXE:-}" ]; then + fallback="$(dirname "$(dirname "$CONDA_EXE")")/etc/profile.d/conda.sh" + [ -f "$fallback" ] && CONDA_SH="$fallback" +fi if [ -z "$CONDA_SH" ]; then echo "ERROR: Could not locate conda.sh." - echo " Install Miniconda to ~/miniconda3 and re-run." - echo " https://docs.conda.io/projects/miniconda/en/latest/" + echo " Install Miniforge to ~/miniforge3 and re-run." + echo " https://github.com/conda-forge/miniforge" echo read -n 1 -s -r -p "Press any key to close this window..." exit 1 diff --git a/launch-native.sh b/launch-native.sh new file mode 100644 index 0000000..8727b93 --- /dev/null +++ b/launch-native.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# QuantUI NATIVE MODE — Linux / WSL launcher +# Run from a WSL Ubuntu (or native Linux) terminal: ./launch-native.sh +# Equivalent to launch-native.command on macOS and launch-native.bat on +# Windows, but for a repo that lives on the native Linux filesystem +# (e.g. a clone at ~/GitHub/QuantUI). Running from the native filesystem +# rather than /mnt/c avoids the 9P "Operation not permitted" errors that +# break editable installs and is dramatically faster for git/builds. +# +# Use this when you have edited quantui/*.py and want to test immediately — +# quantui/*.py changes are always live in editable mode. + +set -eu + +# Resolve script directory so the launcher works no matter where it is run +# from (native ~/… clone or a /mnt/c checkout). +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "QuantUI NATIVE MODE — Local conda env on Linux/WSL, no container" +echo "Use this when you have edited quantui/*.py and want to test immediately." +echo + +# Locate conda.sh. Detect the install rather than assuming one location: +# miniforge (recommended for WSL), miniconda, and anaconda are all supported, +# in home and system prefixes. Falls back to an already-configured conda via +# $CONDA_EXE. +CONDA_SH="" +for candidate in \ + "$HOME/miniforge3/etc/profile.d/conda.sh" \ + "$HOME/miniconda3/etc/profile.d/conda.sh" \ + "$HOME/anaconda3/etc/profile.d/conda.sh" \ + "/opt/miniforge3/etc/profile.d/conda.sh" \ + "/opt/miniconda3/etc/profile.d/conda.sh" \ + "/opt/conda/etc/profile.d/conda.sh"; do + if [ -f "$candidate" ]; then + CONDA_SH="$candidate" + break + fi +done +if [ -z "$CONDA_SH" ] && [ -n "${CONDA_EXE:-}" ]; then + fallback="$(dirname "$(dirname "$CONDA_EXE")")/etc/profile.d/conda.sh" + [ -f "$fallback" ] && CONDA_SH="$fallback" +fi + +if [ -z "$CONDA_SH" ]; then + echo "ERROR: Could not locate conda.sh." + echo " Install Miniforge to ~/miniforge3 and re-run." + echo " https://github.com/conda-forge/miniforge" + exit 1 +fi + +# shellcheck disable=SC1090 +source "$CONDA_SH" +conda activate quantui + +# pip install -e . is skipped when pyproject.toml has not changed since the +# last install (.dev_install_stamp). quantui/*.py changes are always live in +# editable mode — reinstall is only needed after pyproject.toml changes or on +# first use. +if [ ! -f .dev_install_stamp ] || [ pyproject.toml -nt .dev_install_stamp ]; then + echo "Installing quantui in editable mode (first run or pyproject.toml changed)..." + # Must not abort the launch when offline (set -e) — pip fetches build deps + # from PyPI, which hangs/fails with no network. Fail fast + non-fatal; the + # editable source is live regardless of whether the reinstall ran. + if pip install -e . -q --timeout=5 --retries=0; then + touch .dev_install_stamp + else + # Stamp even on failure so offline launches don't retry (and re-delay + # on) pip every time. Re-run `pip install -e .` manually when online if + # you add a real dependency. + echo "[QuantUI] editable reinstall skipped (offline?) - using live source" + touch .dev_install_stamp + fi +fi + +# Clear bytecode and disable .pyc writes. Required when the repo is on a +# /mnt/c (WSL2 DrvFs) checkout, where Windows-side mtime changes are not +# reliably propagated and Python may load stale pre-edit .pyc (see GOTCHAS.md). +# Harmless on a native-filesystem clone, so it is kept for parity. +rm -rf quantui/__pycache__ +export PYTHONDONTWRITEBYTECODE=1 + +# Port 8867 mirrors the Windows/macOS native launchers so the same browser tab +# can be reused across platforms. +PORT=8867 +URL="http://localhost:${PORT}" + +echo "Starting Voilà on ${URL}..." +echo + +# Launch Voilà in the background so we can open the browser, then wait on the +# process so closing this terminal (or Ctrl-C) stops the server. +voila notebooks/molecule_computations.ipynb \ + --no-browser \ + --port="${PORT}" \ + --ServerApp.disable_check_xsrf=True & +VOILA_PID=$! + +# Give Voilà a moment to bind to the port before opening the browser. Try the +# common openers in order; under WSL, wslview/cmd.exe hand off to the Windows +# browser. All are non-fatal — the URL is printed regardless. +sleep 4 +if command -v wslview >/dev/null 2>&1; then + wslview "${URL}" >/dev/null 2>&1 || true +elif command -v xdg-open >/dev/null 2>&1; then + xdg-open "${URL}" >/dev/null 2>&1 || true +elif command -v cmd.exe >/dev/null 2>&1; then + cmd.exe /c start "" "${URL}" >/dev/null 2>&1 || true +fi + +echo +echo "Native dev server running at ${URL}" +echo "All local quantui/*.py changes are live — no rebuild needed." +echo "Press Ctrl-C or close this terminal to stop." +echo + +wait "${VOILA_PID}" From f8fec770e8723cd2d80a50dfb32e283443cb08b1 Mon Sep 17 00:00:00 2001 From: Schultz Lab at NCCU Date: Tue, 21 Jul 2026 18:53:25 -0400 Subject: [PATCH 2/4] Move launcher scripts into launchers/ folder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declutter the repo root by consolidating all 7 launcher scripts into a launchers/ folder. Behaviour is unchanged — each launcher now resolves the repo root as its parent directory: - Shell launchers (launch-native.sh/.command, launch-native-jupyter.sh) cd to /..; the jupyter worker is now self-locating. - Windows .bat launchers compute the repo root via %~dp0.. and point the jupyter worker at ./launchers/launch-native-jupyter.sh. - launch-app.bat still finds quantui.sif next to itself (student download) or in the repo root (dev build). Updated all references in README.md, apptainer/README.md, copilot-instructions.md, .gitignore, the offline-startup test comment, and added a CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/copilot-instructions.md | 3 +-- .gitignore | 2 +- CHANGELOG.md | 9 ++++++++ README.md | 23 ++++++++++--------- apptainer/README.md | 7 +++--- launch-app.bat => launchers/launch-app.bat | 11 +++++---- launch-dev.bat => launchers/launch-dev.bat | 9 +++++--- .../launch-native-jupyter.bat | 15 ++++++------ .../launch-native-jupyter.sh | 6 +++++ .../launch-native.bat | 6 +++-- .../launch-native.command | 3 ++- .../launch-native.sh | 3 ++- scripts/test_offline_startup.py | 2 +- 13 files changed, 63 insertions(+), 36 deletions(-) rename launch-app.bat => launchers/launch-app.bat (60%) rename launch-dev.bat => launchers/launch-dev.bat (79%) rename launch-native-jupyter.bat => launchers/launch-native-jupyter.bat (85%) rename launch-native-jupyter.sh => launchers/launch-native-jupyter.sh (89%) mode change 100644 => 100755 rename launch-native.bat => launchers/launch-native.bat (91%) rename launch-native.command => launchers/launch-native.command (98%) mode change 100644 => 100755 rename launch-native.sh => launchers/launch-native.sh (98%) mode change 100644 => 100755 diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 5e36262..938cc8a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -76,8 +76,7 @@ QuantUI/ │ ├── quantui.def ← Apptainer container definition │ └── build.sh ← Build script ├── local-setup/ ← Conda environment YAMLs -├── launch-app.bat ← Windows double-click launcher (Voilà app mode) -├── launch-dev.bat ← Windows double-click launcher (JupyterLab mode) +├── launchers/ ← Double-click launchers (Windows .bat, macOS .command, Linux/WSL .sh) ├── CHANGELOG.md ← Release history (Keep a Changelog format) ├── pyproject.toml ← Package config (name: quantui, imports as quantui) └── pytest.ini ← pytest configuration diff --git a/.gitignore b/.gitignore index 20f1cf4..7846e81 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Dev launcher stamp (written by launch-native.bat to skip redundant pip install) +# Dev launcher stamp (written by launchers/launch-native.* to skip redundant pip install) .dev_install_stamp # Python diff --git a/CHANGELOG.md b/CHANGELOG.md index 84abbd0..5a9e3f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,15 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht - **One-click "Calc. Reorganization Energy" button** — sets the calculation type to Reorganization Energy, defaults the channel to both hole + electron, and launches the run in a single click. + +### Changed + +- **All launcher scripts moved into a `launchers/` folder** to declutter the repo + root. Behaviour is unchanged — each launcher now resolves the repo root as its + parent directory. `launchers/launch-app.bat` still finds `quantui.sif` next to + itself (student download) or in the repo root (dev build). Docs and shortcuts + that referenced the old top-level paths were updated. + ## [0.4.1] - 2026-07-16 Bug-fix and hardening release from a full repository audit. No new features and diff --git a/README.md b/README.md index bd5b4cc..f8c40ae 100644 --- a/README.md +++ b/README.md @@ -194,9 +194,9 @@ no rebuild. | Platform | File | Action | | --- | --- | --- | -| Windows | [`launch-native.bat`](launch-native.bat) | Activates the `quantui` conda env inside WSL Ubuntu, runs Voilà, and opens `http://localhost:8867` | -| macOS | [`launch-native.command`](launch-native.command) | Activates the local `quantui` conda env directly (no WSL needed) and does the same | -| Linux / WSL | [`launch-native.sh`](launch-native.sh) | Run `./launch-native.sh` from a Linux or WSL terminal; activates `quantui` and does the same | +| Windows | [`launchers/launch-native.bat`](launchers/launch-native.bat) | Activates the `quantui` conda env inside WSL Ubuntu, runs Voilà, and opens `http://localhost:8867` | +| macOS | [`launchers/launch-native.command`](launchers/launch-native.command) | Activates the local `quantui` conda env directly (no WSL needed) and does the same | +| Linux / WSL | [`launchers/launch-native.sh`](launchers/launch-native.sh) | Run `./launchers/launch-native.sh` from a Linux or WSL terminal; activates `quantui` and does the same | All launchers reuse port `8867`, so you can keep the same browser tab pinned across platforms. They **auto-detect your conda installation** — miniforge @@ -216,13 +216,13 @@ prefix — so no path editing is needed regardless of which you installed. > ``` > > Then open it in VS Code with `code .` (installs the WSL server and reopens -> the window connected to WSL). `launch-native.sh` resolves its own location, -> so it works from any clone path. +> the window connected to WSL). `launchers/launch-native.sh` resolves its own +> location, so it works from any clone path. ### Windows — pin to the Start menu -1. Right-click [`launch-native.bat`](launch-native.bat) in File Explorer - → **Send to** → **Desktop (create shortcut)**. +1. Right-click [`launchers/launch-native.bat`](launchers/launch-native.bat) in + File Explorer → **Send to** → **Desktop (create shortcut)**. 2. Rename the shortcut to something friendly like `QuantUI`. 3. *(Optional)* Right-click the shortcut → **Properties** → **Change Icon...** and point at `docs\logo.ico` for a proper app icon. @@ -241,7 +241,8 @@ in your browser. ### macOS — pin to the Dock / Launchpad -**Quickest:** double-click [`launch-native.command`](launch-native.command) +**Quickest:** double-click +[`launchers/launch-native.command`](launchers/launch-native.command) from Finder. macOS will open Terminal, run the script, and pop the app open in your browser. The first launch is gated by Gatekeeper: right-click the file → **Open** → **Open** to clear it (one time only). @@ -258,7 +259,7 @@ application so it lives in Launchpad and pins to the Dock. your clone lives elsewhere): ```bash - "$HOME/path/to/QuantUI/launch-native.command" + "$HOME/path/to/QuantUI/launchers/launch-native.command" ``` 4. **File → Save** → name it `QuantUI` → save into `/Applications`. @@ -272,8 +273,8 @@ You now have a real `.app` you can launch from Spotlight, Launchpad, or the Dock — it just runs the `.command` script under the hood, so any `quantui/*.py` edits take effect immediately on the next launch. -> **Linux users:** the same `launch-native.command` script works from a -> terminal — `./launch-native.command`. To wire it into your desktop +> **Linux users:** the same `launchers/launch-native.command` script works from +> a terminal — `./launchers/launch-native.command`. To wire it into your desktop > environment as a pinned app, create a `.desktop` entry pointing at the > script. diff --git a/apptainer/README.md b/apptainer/README.md index dcdeadd..f2cbd97 100644 --- a/apptainer/README.md +++ b/apptainer/README.md @@ -105,12 +105,13 @@ the `.def` file copies the entire repo root into the container with ### Windows — double-click launchers (easiest) -Two `.bat` files in the repo root handle WSL and browser launch automatically: +Two `.bat` files in the repo's `launchers/` folder handle WSL and browser launch +automatically: | File | Purpose | | --- | --- | -| `launch-app.bat` | Student-facing app — uses the baked-in notebook | -| `launch-dev.bat` | Development mode — uses local `notebooks/` (no rebuild needed for notebook edits) | +| `launchers/launch-app.bat` | Student-facing app — uses the baked-in notebook | +| `launchers/launch-dev.bat` | Development mode — uses local `notebooks/` (no rebuild needed for notebook edits) | Double-click either file. The browser opens automatically at [http://localhost:8866](http://localhost:8866). diff --git a/launch-app.bat b/launchers/launch-app.bat similarity index 60% rename from launch-app.bat rename to launchers/launch-app.bat index aca1f79..eb661d1 100644 --- a/launch-app.bat +++ b/launchers/launch-app.bat @@ -2,8 +2,11 @@ echo QuantUI — Starting... echo. -REM Check that the .sif exists before trying to launch -if not exist "%~dp0quantui.sif" ( +REM Locate quantui.sif — next to this launcher (student download) or in the +REM repo root one level up (dev build via apptainer/build.sh). +set "SIFDIR=%~dp0" +if not exist "%SIFDIR%quantui.sif" set "SIFDIR=%~dp0..\" +if not exist "%SIFDIR%quantui.sif" ( echo ERROR: quantui.sif not found. echo Build it first: bash apptainer/build.sh echo Or download it from the GitHub Releases page. @@ -11,8 +14,8 @@ if not exist "%~dp0quantui.sif" ( exit /b 1 ) -REM Convert the Windows repo path to a WSL path for portability -for /f "delims=" %%i in ('wsl wslpath -a "%~dp0"') do set WSLPATH=%%i +REM Convert the folder holding the .sif to a WSL path for portability +for /f "delims=" %%i in ('wsl wslpath -a "%SIFDIR%"') do set WSLPATH=%%i REM Launch Voila in a new WSL window (stays open so you can see logs) start "QuantUI" wsl -d Ubuntu -- bash -c "cd '%WSLPATH%' && apptainer run quantui.sif app" diff --git a/launch-dev.bat b/launchers/launch-dev.bat similarity index 79% rename from launch-dev.bat rename to launchers/launch-dev.bat index 2f66058..8f3a8c1 100644 --- a/launch-dev.bat +++ b/launchers/launch-dev.bat @@ -2,7 +2,10 @@ echo QuantUI DEV MODE — Using local notebook (no rebuild needed) echo. -if not exist "%~dp0quantui.sif" ( +REM Repo root is one level up from this launchers/ folder. +for %%i in ("%~dp0..") do set "REPO=%%~fi" + +if not exist "%REPO%\quantui.sif" ( echo ERROR: quantui.sif not found. pause exit /b 1 @@ -14,8 +17,8 @@ echo Edits to quantui/*.py require a container rebuild to take effect. echo For package-level dev, use launch-native.bat instead. echo. -REM Convert the Windows repo path to a WSL path for portability -for /f "delims=" %%i in ('wsl wslpath -a "%~dp0"') do set WSLPATH=%%i +REM Convert the repo root to a WSL path for portability +for /f "delims=" %%i in ('wsl wslpath -a "%REPO%"') do set WSLPATH=%%i REM Uses the local notebook on disk instead of the baked-in copy. REM Edits to notebooks/ take effect immediately — no container rebuild needed. diff --git a/launch-native-jupyter.bat b/launchers/launch-native-jupyter.bat similarity index 85% rename from launch-native-jupyter.bat rename to launchers/launch-native-jupyter.bat index 14b03f8..e28fd81 100644 --- a/launch-native-jupyter.bat +++ b/launchers/launch-native-jupyter.bat @@ -3,18 +3,19 @@ echo QuantUI NATIVE JUPYTER MODE -- Local conda env in WSL, no container echo Use this when you have edited quantui/*.py and want JupyterLab. echo. -REM Convert the Windows repo path to a WSL path for portability -set "WIN_REPO=%~dp0." -for /f "delims=" %%i in ('wsl wslpath -a "%WIN_REPO%"') do set WSLPATH=%%i +REM Repo root is one level up from this launchers/ folder; convert it to a WSL +REM path for portability. +for %%i in ("%~dp0..") do set "REPO=%%~fi" +for /f "delims=" %%i in ('wsl wslpath -a "%REPO%"') do set WSLPATH=%%i if not defined WSLPATH ( - echo ERROR: Could not resolve a WSL path for %WIN_REPO% + echo ERROR: Could not resolve a WSL path for %REPO% echo Try this command manually: - echo wsl wslpath -a "%WIN_REPO%" + echo wsl wslpath -a "%REPO%" echo. pause exit /b 1 ) -set LOGFILE=%~dp0logs\native-jupyter.log +set "LOGFILE=%REPO%\logs\native-jupyter.log" echo Startup log: %LOGFILE% echo. @@ -30,7 +31,7 @@ REM Clears quantui/__pycache__ on every launch to prevent stale .pyc bytecode REM (WSL2 DrvFs does not reliably propagate Windows-side mtime changes, so Python REM may load pre-edit bytecode even after source changes -- see GOTCHAS.md). REM PYTHONDONTWRITEBYTECODE=1 prevents a new stale cache from accumulating. -start "QuantUI [native-jupyter]" wsl -d Ubuntu --cd "%WSLPATH%" -- bash ./launch-native-jupyter.sh +start "QuantUI [native-jupyter]" wsl -d Ubuntu --cd "%WSLPATH%" -- bash ./launchers/launch-native-jupyter.sh echo Waiting for JupyterLab to start on localhost:8868... set MAX_WAIT=45 diff --git a/launch-native-jupyter.sh b/launchers/launch-native-jupyter.sh old mode 100644 new mode 100755 similarity index 89% rename from launch-native-jupyter.sh rename to launchers/launch-native-jupyter.sh index 02c32ef..66dead4 --- a/launch-native-jupyter.sh +++ b/launchers/launch-native-jupyter.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash set -euo pipefail +# Repo root is one level up from this launchers/ folder. cd there so every +# relative path below (logs/, pyproject.toml, quantui/, notebooks/) resolves +# regardless of the caller's working directory. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR/.." + LOG_FILE="logs/native-jupyter.log" mkdir -p "$(dirname "$LOG_FILE")" diff --git a/launch-native.bat b/launchers/launch-native.bat similarity index 91% rename from launch-native.bat rename to launchers/launch-native.bat index 78db1f2..25a4ea9 100644 --- a/launch-native.bat +++ b/launchers/launch-native.bat @@ -3,8 +3,10 @@ echo QuantUI NATIVE MODE — Local conda env in WSL, no container echo Use this when you have edited quantui/*.py and want to test immediately. echo. -REM Convert the Windows repo path to a WSL path for portability -for /f "delims=" %%i in ('wsl wslpath -a "%~dp0"') do set WSLPATH=%%i +REM Repo root is one level up from this launchers/ folder; convert it to a WSL +REM path for portability. +for %%i in ("%~dp0..") do set "REPO=%%~fi" +for /f "delims=" %%i in ('wsl wslpath -a "%REPO%"') do set WSLPATH=%%i REM Runs Voila directly from the quantui conda env inside WSL. REM pip install -e . is skipped when pyproject.toml has not changed since the diff --git a/launch-native.command b/launchers/launch-native.command old mode 100644 new mode 100755 similarity index 98% rename from launch-native.command rename to launchers/launch-native.command index 1f1593a..077cf21 --- a/launch-native.command +++ b/launchers/launch-native.command @@ -11,7 +11,8 @@ set -eu # Resolve script directory so double-click from any location works. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" +# Repo root is one level up from this launchers/ folder. +cd "$SCRIPT_DIR/.." echo "QuantUI NATIVE MODE — Local conda env on macOS, no container" echo "Use this when you have edited quantui/*.py and want to test immediately." diff --git a/launch-native.sh b/launchers/launch-native.sh old mode 100644 new mode 100755 similarity index 98% rename from launch-native.sh rename to launchers/launch-native.sh index 8727b93..e42a285 --- a/launch-native.sh +++ b/launchers/launch-native.sh @@ -15,7 +15,8 @@ set -eu # Resolve script directory so the launcher works no matter where it is run # from (native ~/… clone or a /mnt/c checkout). SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" +# Repo root is one level up from this launchers/ folder. +cd "$SCRIPT_DIR/.." echo "QuantUI NATIVE MODE — Local conda env on Linux/WSL, no container" echo "Use this when you have edited quantui/*.py and want to test immediately." diff --git a/scripts/test_offline_startup.py b/scripts/test_offline_startup.py index 869f887..62ceaf8 100644 --- a/scripts/test_offline_startup.py +++ b/scripts/test_offline_startup.py @@ -13,7 +13,7 @@ blocks waiting for a connect timeout when there's no network. It runs without a browser or a server, so it's fast and deterministic. -NOTE: this checks the *app*. The native launchers (``launch-native.bat`` etc.) +NOTE: this checks the *app*. The native launchers (``launchers/launch-native.bat`` etc.) also run ``pip install -e .`` when ``pyproject.toml`` changes — that step fetches build deps from PyPI and will hang/fail offline, so the launchers run it fail-fast + non-fatal. If "doesn't start up offline" recurs, check BOTH: this From 83265bc877fd8286308ac2e79ac6db8f7463c7db Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Jul 2026 13:53:09 +0000 Subject: [PATCH 3/4] Fix Apptainer build status message --- apptainer/quantui.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apptainer/quantui.def b/apptainer/quantui.def index 5f5fee5..e34b36a 100644 --- a/apptainer/quantui.def +++ b/apptainer/quantui.def @@ -43,7 +43,7 @@ FROM: condaforge/miniforge3:latest export PATH="/opt/conda/bin:${PATH}" echo "Installing dependencies via mamba (libmamba solver — the old classic" - echo "conda solver hangs for hours on this pyscf + rdkit + jupyterlab spec)..." + echo "conda solver hangs for hours on this pyscf + rdkit + jupyterlab spec)." # conda-forge only, strict priority: avoids mixing in the base image's # implicit 'defaults' channel, which both slows the solve and pulls from a # channel with separate terms of service. From 6540ca1ccbf376a5c632f2e6177154c0ba6362a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Jul 2026 13:53:42 +0000 Subject: [PATCH 4/4] Clarify Apptainer build status message --- apptainer/quantui.def | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apptainer/quantui.def b/apptainer/quantui.def index e34b36a..c669a42 100644 --- a/apptainer/quantui.def +++ b/apptainer/quantui.def @@ -42,8 +42,7 @@ FROM: condaforge/miniforge3:latest %post export PATH="/opt/conda/bin:${PATH}" - echo "Installing dependencies via mamba (libmamba solver — the old classic" - echo "conda solver hangs for hours on this pyscf + rdkit + jupyterlab spec)." + echo "Installing dependencies via mamba (libmamba solver — the old classic conda solver hangs for hours on this pyscf + rdkit + jupyterlab spec)." # conda-forge only, strict priority: avoids mixing in the base image's # implicit 'defaults' channel, which both slows the solve and pulls from a # channel with separate terms of service.