From 3afc7b6896304783988a4bae3ad5728cc888893f Mon Sep 17 00:00:00 2001 From: Jonathan Schultz Date: Sat, 26 Sep 2026 16:56:27 +0000 Subject: [PATCH 1/2] fix(dev): install with `python -m pip` in the cloud SessionStart hook The hook upgraded setuptools with `python -m pip` but installed the package with bare `pip`. In the cloud image `pip` is /usr/bin/pip (distro Python) while `python` is /usr/local/bin/python, so the install ran against the distro setuptools, failed to build pyscf-properties, and (under set -e) left the session with nothing installed. This is the "pyscf-properties uninstallable in cloud" watchlist item; it was never environmental. Verified: with pyscf-properties uninstalled, the fixed hook reinstalls it and exits 0, and the full `pytest -m "not network"` suite passes in the cloud container (previously 23 NMR/Raman failures). Contributions: - Claude (Opus 5.5): code edits, review, and conceptual discussion - Jonathan Schultz: overall vision, planning, review, and orchestration Co-authored-by: Jonathan Schultz Co-authored-by: Claude Opus 5.5 --- .claude/hooks/session-start.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh index e726795..ead61e0 100755 --- a/.claude/hooks/session-start.sh +++ b/.claude/hooks/session-start.sh @@ -29,7 +29,13 @@ python -m pip install --upgrade --ignore-installed setuptools wheel || true # Editable install with the same extras CI uses. Editable + plain `install` # (not `ci`-style clean installs) so the resolved deps are cached in the # container image for later sessions. -pip install -e ".[pyscf,ase,dev,xtb]" +# +# `python -m pip`, not bare `pip`: in the cloud image `pip` is /usr/bin/pip +# (the distro Python) while `python` is /usr/local/bin/python. The setuptools +# upgrade above targets `python`, so a bare `pip` install used the distro +# setuptools and failed to build pyscf-properties, which left the session +# with nothing installed. +python -m pip install -e ".[pyscf,ase,dev,xtb]" echo "QuantUI cloud env ready: package + [pyscf,ase,dev,xtb] installed." >&2 From ea0156c9dd68fd794805feeca7779c162dfadc64 Mon Sep 17 00:00:00 2001 From: Jonathan Schultz Date: Sat, 26 Sep 2026 16:56:27 +0000 Subject: [PATCH 2/2] fix(theme): theme-aware axis and zero lines on Plotly charts _apply_plotly_theme() set background, font and grid colors but not linecolor/zerolinecolor, which stayed at the plotly_white template's pale blue-gray default, meant for white backgrounds. Both now use the palette's border_strong (new plotly_colors()["axis_line_color"]), one step stronger than the grid, so axes stay visible and consistent on dark palettes. M-THEME's remaining "hex tail" item. Still needs a Voila visual pass on a dark palette. Contributions: - Claude (Opus 5.5): code edits, review, and conceptual discussion - Jonathan Schultz: overall vision, planning, review, and orchestration Co-authored-by: Jonathan Schultz Co-authored-by: Claude Opus 5.5 --- quantui/app.py | 12 ++++++++++-- quantui/theme.py | 4 ++++ tests/test_theme_contrast.py | 3 +++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/quantui/app.py b/quantui/app.py index 67a8757..ad47e2d 100644 --- a/quantui/app.py +++ b/quantui/app.py @@ -3564,8 +3564,16 @@ def _apply_plotly_theme(self, fig) -> None: plot_bgcolor="rgba(0,0,0,0)", paper_bgcolor="rgba(0,0,0,0)", font=dict(color=tc["font_color"]), - xaxis=dict(gridcolor=tc["grid_color"]), - yaxis=dict(gridcolor=tc["grid_color"]), + xaxis=dict( + gridcolor=tc["grid_color"], + linecolor=tc["axis_line_color"], + zerolinecolor=tc["axis_line_color"], + ), + yaxis=dict( + gridcolor=tc["grid_color"], + linecolor=tc["axis_line_color"], + zerolinecolor=tc["axis_line_color"], + ), ) def _set_html_output(self, out: widgets.Output, html: str) -> None: diff --git a/quantui/theme.py b/quantui/theme.py index c295f5e..bd6cdde 100644 --- a/quantui/theme.py +++ b/quantui/theme.py @@ -646,6 +646,10 @@ def plotly_colors(palette_id: str) -> dict: "paper_bgcolor": palette.page_bg, "font_color": palette.text_strong, "grid_color": palette.border, + # Axis and zero lines: one step stronger than the grid, so they stay + # visible on dark palettes (the plotly_white default is a pale + # blue-gray meant for white backgrounds). + "axis_line_color": palette.border_strong, "scene_bgcolor": "#000000" if palette.is_dark else "#ffffff", } diff --git a/tests/test_theme_contrast.py b/tests/test_theme_contrast.py index 3a22160..f57aac9 100644 --- a/tests/test_theme_contrast.py +++ b/tests/test_theme_contrast.py @@ -86,6 +86,9 @@ def test_plotly_colours_track_palette(self, palette_id): palette = theme.get_palette(palette_id) assert colours["plot_bgcolor"] == palette.bg_panel assert colours["paper_bgcolor"] == palette.page_bg + # Axis/zero lines follow the palette too (M-THEME), not the + # plotly_white template's pale default. + assert colours["axis_line_color"] == palette.border_strong class TestBordersMeetContrastBar: