somratpro Claude Sonnet 4.5 commited on
Commit
80dd8e5
Β·
1 Parent(s): 6b48202

fix: center login form, simplify startup logs

Browse files

login.html:
- Fix token input/button centering (remove Bootstrap navbar pull-left)
- Update token hint: GATEWAY_TOKEN is default, JUPYTER_TOKEN overrides
- Remove stale "default token is huggingface" text

start.sh:
- Silence GATEWAY_TOKEN auto-enable message (was noisy debug output)
- Redirect pip install output to /dev/null, show one-liner status
- Remove "JUPYTER_TOKEN not set β€” using GATEWAY_TOKEN" noise
- Replace "DEV_MODE enabled (false) β€” starting JupyterLab..." with clean
"Terminal : starting / started / installed" format
- Remove "Jupyter terminal disabled for this boot" noise
- Remove "Private :" line from startup summary
- Clean DevData restore messages to match consistent format

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Files changed (2) hide show
  1. login.html +12 -22
  2. start.sh +11 -17
login.html CHANGED
@@ -8,36 +8,26 @@
8
  <img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" alt="Hugging Face Logo" style="max-width: 120px; margin-bottom: 24px;">
9
  <h3>HuggingClaw Terminal</h3>
10
  <h4>Welcome to JupyterLab</h4>
11
- <h5>The default token is <span style="color:orange;">huggingface</span></h5>
12
- <p style="color:#666;">This terminal is mounted at <code>/terminal/</code> inside the same Hugging Face Space as the OpenClaw UI.</p>
13
 
14
  {% if login_available %}
15
- <div class="row" style="display:flex; justify-content:center; margin-top:24px;">
16
- <div class="navbar col-sm-8">
17
- <div class="navbar-inner">
18
- <div class="container">
19
- <div class="center-nav">
20
- <form action="{{base_url}}login?next={{next}}" method="post" class="navbar-form pull-left">
21
- {{ xsrf_form_html() | safe }}
22
- {% if token_available %}
23
- <label for="password_input"><strong>{% trans %}Jupyter token <span title="This is the secret you set up when deploying your JupyterLab terminal">β“˜</span> {% endtrans %}</strong></label>
24
- {% else %}
25
- <label for="password_input"><strong>{% trans %}Jupyter password:{% endtrans %}</strong></label>
26
- {% endif %}
27
- <input type="password" name="password" id="password_input" class="form-control">
28
- <button type="submit" class="btn btn-default" id="login_submit">{% trans %}Log in{% endtrans %}</button>
29
- </form>
30
- </div>
31
- </div>
32
- </div>
33
- </div>
34
  </div>
35
  {% else %}
36
  <p>{% trans %}No login available, you shouldn't be seeing this page.{% endtrans %}</p>
37
  {% endif %}
38
 
39
  <h5 style="margin-top:28px;"><a href="/dashboard">Back to HuggingClaw dashboard</a></h5>
40
- <p>This login page is based on the Hugging Face JupyterLab Space template.</p>
41
 
42
  {% if message %}
43
  <div class="row">
 
8
  <img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" alt="Hugging Face Logo" style="max-width: 120px; margin-bottom: 24px;">
9
  <h3>HuggingClaw Terminal</h3>
10
  <h4>Welcome to JupyterLab</h4>
11
+ <p style="color:#666;">Token defaults to your <code>GATEWAY_TOKEN</code>. Set <code>JUPYTER_TOKEN</code> to override.</p>
 
12
 
13
  {% if login_available %}
14
+ <div style="display:flex; justify-content:center; margin-top:24px;">
15
+ <form action="{{base_url}}login?next={{next}}" method="post" style="display:flex; align-items:center; gap:8px;">
16
+ {{ xsrf_form_html() | safe }}
17
+ {% if token_available %}
18
+ <label for="password_input"><strong>{% trans %}Jupyter token <span title="Your GATEWAY_TOKEN (or JUPYTER_TOKEN if set)">β“˜</span>{% endtrans %}</strong></label>
19
+ {% else %}
20
+ <label for="password_input"><strong>{% trans %}Jupyter password:{% endtrans %}</strong></label>
21
+ {% endif %}
22
+ <input type="password" name="password" id="password_input" class="form-control">
23
+ <button type="submit" class="btn btn-default" id="login_submit">{% trans %}Log in{% endtrans %}</button>
24
+ </form>
 
 
 
 
 
 
 
 
25
  </div>
26
  {% else %}
27
  <p>{% trans %}No login available, you shouldn't be seeing this page.{% endtrans %}</p>
28
  {% endif %}
29
 
30
  <h5 style="margin-top:28px;"><a href="/dashboard">Back to HuggingClaw dashboard</a></h5>
 
31
 
32
  {% if message %}
33
  <div class="row">
start.sh CHANGED
@@ -94,7 +94,7 @@ fi
94
  # GATEWAY_TOKEN doubles as JUPYTER_TOKEN (see start_jupyter_once) β€” no extra secret required.
95
  if [ "$DEV_MODE_ENABLED" != "true" ] && [ -z "${DEV_MODE:-}" ] && [ -n "${GATEWAY_TOKEN:-}" ]; then
96
  DEV_MODE_ENABLED=true
97
- echo "GATEWAY_TOKEN set and DEV_MODE not explicitly configured β€” auto-enabling terminal (set DEV_MODE=false to opt out)"
98
  fi
99
  SYNC_INTERVAL="$(trim_var "${SYNC_INTERVAL:-180}")"
100
  DEVDATA_DATASET_NAME="$(trim_var "${DEVDATA_DATASET_NAME:-huggingclaw-devdata}")"
@@ -768,12 +768,12 @@ export PATH="$HOME/.local/bin:$PATH"
768
 
769
  # Runtime install fallback: only attempt if DEV_MODE is enabled but install failed during build
770
  if [ "$DEV_MODE_ENABLED" = "true" ] && ! python3 -c "import jupyterlab" >/dev/null 2>&1; then
771
- echo "DEV_MODE enabled but jupyter-lab is missing; attempting runtime install..."
772
- if python3 -m pip install --user --no-cache-dir --break-system-packages "jupyterlab>=4.2,<5" "tornado>=6.3" "ipywidgets>=8.1"; then
773
- echo "Runtime Jupyter install complete."
774
  python3 -c "from pathlib import Path; import shutil, jupyter_server; d=Path(jupyter_server.__file__).parent/'templates'; d.mkdir(parents=True,exist_ok=True); shutil.copyfile('/home/node/app/login.html', d/'login.html')" || true
775
  else
776
- echo "WARNING: Runtime Jupyter install failed; disabling terminal for this boot."
777
  RUNTIME_JUPYTER_ENABLED=false
778
  fi
779
  fi
@@ -789,7 +789,6 @@ if [ -n "${SPACE_HOST:-}" ]; then
789
  else
790
  echo "Routes : /app/ (Control UI)"
791
  fi
792
- echo "Private : open the Hugging Face App tab first; raw https://${SPACE_HOST}/... links can show HF 404 without the embedded Space session."
793
  fi
794
  echo ""
795
 
@@ -858,7 +857,6 @@ start_jupyter_once() {
858
  # reuse GATEWAY_TOKEN. Both protect the same Space, so the credential is equivalent.
859
  if { [ -z "${JUPYTER_TOKEN:-}" ] || [ "${JUPYTER_TOKEN}" = "huggingface" ]; } && [ -n "${GATEWAY_TOKEN:-}" ]; then
860
  JUPYTER_TOKEN="$GATEWAY_TOKEN"
861
- echo "JUPYTER_TOKEN not set β€” using GATEWAY_TOKEN as terminal auth token"
862
  fi
863
 
864
  # Security guard: refuse to start JupyterLab with the insecure default token.
@@ -891,7 +889,7 @@ start_jupyter_once() {
891
  # Pre-create runtime directory
892
  mkdir -p "$JUPYTER_ROOT_DIR/.jupyter"
893
 
894
- echo "DEV_MODE enabled (${DEV_MODE_RAW}) β€” starting JupyterLab terminal on internal port 8888 (path: /terminal/) with root: $JUPYTER_ROOT_DIR"
895
  JUPYTER_LOG_FILE="/tmp/jupyterlab.log"
896
 
897
  # Use explicit Python to avoid PATH issues; set memory-friendly limits
@@ -917,7 +915,7 @@ start_jupyter_once() {
917
  >> "$JUPYTER_LOG_FILE" 2>&1 &
918
  JUPYTER_PID=$!
919
  export JUPYTER_PID
920
- echo "JupyterLab started (PID: $JUPYTER_PID)"
921
  }
922
 
923
  # BUG FIX #3: DevData restore must happen BEFORE JupyterLab starts.
@@ -930,9 +928,9 @@ if [ "$RUNTIME_JUPYTER_ENABLED" = "true" ] && \
930
  [ -n "${HF_TOKEN:-}" ] && \
931
  [ -f "/home/node/app/jupyter-devdata-sync.py" ] && \
932
  [ "${DEVDATA_DATASET_NAME:-huggingclaw-devdata}" != "${BACKUP_DATASET_NAME:-huggingclaw-backup}" ]; then
933
- echo "DevData : restoring workspace from ${DEVDATA_DATASET_NAME:-huggingclaw-devdata} (before JupyterLab starts)..."
934
- python3 /home/node/app/jupyter-devdata-sync.py --restore || \
935
- echo "DevData : restore warning (non-fatal); continuing startup."
936
  fi
937
 
938
  # Fix: reinstall jsonschema AFTER devdata restore β€” restore can overwrite a broken
@@ -940,9 +938,7 @@ fi
940
  # JupyterLab to crash with a circular import error on every boot.
941
  if [ "$DEV_MODE_ENABLED" = "true" ]; then
942
  if ! python3 -c "import jsonschema" >/dev/null 2>&1; then
943
- echo "DevData : jsonschema broken after restore β€” reinstalling (circular import fix)..."
944
- python3 -m pip install --force-reinstall --no-cache-dir --break-system-packages "jsonschema>=4.0" >/dev/null 2>&1 || true
945
- echo "DevData : jsonschema reinstall done."
946
  fi
947
  fi
948
 
@@ -950,8 +946,6 @@ fi
950
  # Accessible via /terminal/ path through the health-server proxy
951
  if [ "$RUNTIME_JUPYTER_ENABLED" = "true" ]; then
952
  start_jupyter_once
953
- else
954
- echo "Jupyter terminal disabled for this boot (DEV_MODE=${DEV_MODE_RAW})."
955
  fi
956
 
957
  if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then
 
94
  # GATEWAY_TOKEN doubles as JUPYTER_TOKEN (see start_jupyter_once) β€” no extra secret required.
95
  if [ "$DEV_MODE_ENABLED" != "true" ] && [ -z "${DEV_MODE:-}" ] && [ -n "${GATEWAY_TOKEN:-}" ]; then
96
  DEV_MODE_ENABLED=true
97
+ : # auto-enable is silent; set DEV_MODE=false to opt out
98
  fi
99
  SYNC_INTERVAL="$(trim_var "${SYNC_INTERVAL:-180}")"
100
  DEVDATA_DATASET_NAME="$(trim_var "${DEVDATA_DATASET_NAME:-huggingclaw-devdata}")"
 
768
 
769
  # Runtime install fallback: only attempt if DEV_MODE is enabled but install failed during build
770
  if [ "$DEV_MODE_ENABLED" = "true" ] && ! python3 -c "import jupyterlab" >/dev/null 2>&1; then
771
+ echo "Terminal : installing JupyterLab..."
772
+ if python3 -m pip install -q --user --no-cache-dir --break-system-packages "jupyterlab>=4.2,<5" "tornado>=6.3" "ipywidgets>=8.1" >/dev/null 2>&1; then
773
+ echo "Terminal : installed"
774
  python3 -c "from pathlib import Path; import shutil, jupyter_server; d=Path(jupyter_server.__file__).parent/'templates'; d.mkdir(parents=True,exist_ok=True); shutil.copyfile('/home/node/app/login.html', d/'login.html')" || true
775
  else
776
+ echo "Terminal : install failed β€” disabling for this boot"
777
  RUNTIME_JUPYTER_ENABLED=false
778
  fi
779
  fi
 
789
  else
790
  echo "Routes : /app/ (Control UI)"
791
  fi
 
792
  fi
793
  echo ""
794
 
 
857
  # reuse GATEWAY_TOKEN. Both protect the same Space, so the credential is equivalent.
858
  if { [ -z "${JUPYTER_TOKEN:-}" ] || [ "${JUPYTER_TOKEN}" = "huggingface" ]; } && [ -n "${GATEWAY_TOKEN:-}" ]; then
859
  JUPYTER_TOKEN="$GATEWAY_TOKEN"
 
860
  fi
861
 
862
  # Security guard: refuse to start JupyterLab with the insecure default token.
 
889
  # Pre-create runtime directory
890
  mkdir -p "$JUPYTER_ROOT_DIR/.jupyter"
891
 
892
+ echo "Terminal : starting (root: $JUPYTER_ROOT_DIR)"
893
  JUPYTER_LOG_FILE="/tmp/jupyterlab.log"
894
 
895
  # Use explicit Python to avoid PATH issues; set memory-friendly limits
 
915
  >> "$JUPYTER_LOG_FILE" 2>&1 &
916
  JUPYTER_PID=$!
917
  export JUPYTER_PID
918
+ echo "Terminal : started (PID: $JUPYTER_PID)"
919
  }
920
 
921
  # BUG FIX #3: DevData restore must happen BEFORE JupyterLab starts.
 
928
  [ -n "${HF_TOKEN:-}" ] && \
929
  [ -f "/home/node/app/jupyter-devdata-sync.py" ] && \
930
  [ "${DEVDATA_DATASET_NAME:-huggingclaw-devdata}" != "${BACKUP_DATASET_NAME:-huggingclaw-backup}" ]; then
931
+ echo "DevData : restoring workspace..."
932
+ python3 /home/node/app/jupyter-devdata-sync.py --restore 2>/dev/null || \
933
+ echo "DevData : restore warning (non-fatal); continuing startup."
934
  fi
935
 
936
  # Fix: reinstall jsonschema AFTER devdata restore β€” restore can overwrite a broken
 
938
  # JupyterLab to crash with a circular import error on every boot.
939
  if [ "$DEV_MODE_ENABLED" = "true" ]; then
940
  if ! python3 -c "import jsonschema" >/dev/null 2>&1; then
941
+ python3 -m pip install -q --force-reinstall --no-cache-dir --break-system-packages "jsonschema>=4.0" >/dev/null 2>&1 || true
 
 
942
  fi
943
  fi
944
 
 
946
  # Accessible via /terminal/ path through the health-server proxy
947
  if [ "$RUNTIME_JUPYTER_ENABLED" = "true" ]; then
948
  start_jupyter_once
 
 
949
  fi
950
 
951
  if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then