somratpro Claude Sonnet 4.5 commited on
Commit
273aafd
Β·
1 Parent(s): 7807f9d

feat: auto-enable terminal when GATEWAY_TOKEN is set

Browse files

- health-server.js: JUPYTER_ENABLED is true when GATEWAY_TOKEN is set,
no DEV_MODE required
- start.sh: auto-sets DEV_MODE_ENABLED when GATEWAY_TOKEN is present
and DEV_MODE was not explicitly configured; GATEWAY_TOKEN used as
JUPYTER_TOKEN fallback inside start_jupyter_once()
- README: update all references to reflect new out-of-the-box behavior

Users with GATEWAY_TOKEN set get the terminal button and terminal access
automatically. Set DEV_MODE=false to opt out. Set JUPYTER_TOKEN to
override the credential.

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

Files changed (3) hide show
  1. README.md +7 -5
  2. health-server.js +4 -1
  3. start.sh +13 -0
README.md CHANGED
@@ -20,7 +20,7 @@ secrets:
20
  - name: GATEWAY_TOKEN
21
  description: "Strong token to secure your OpenClaw Control UI (generate: openssl rand -hex 32)."
22
  - name: JUPYTER_TOKEN
23
- description: "Optional strong token for the JupyterLab terminal at /terminal/ (defaults to huggingface)."
24
  - name: CLOUDFLARE_WORKERS_TOKEN
25
  description: "Cloudflare API token β€” auto-creates a Worker proxy and KeepAlive monitor."
26
  - name: TELEGRAM_ALLOWED_USERS
@@ -78,7 +78,7 @@ secrets:
78
  - πŸ“Š **Visual Dashboard:** Beautiful Web UI to monitor uptime, sync status, and active models.
79
  - πŸ”” **Webhooks:** Get notified on restarts or backup failures via standard webhooks.
80
  - πŸ” **Flexible Auth:** Secure the Control UI with either a gateway token or password.
81
- - πŸ’» **Optional Dev Terminal:** JupyterLab is available at `/terminal/` only when `DEV_MODE=true` (disabled by default).
82
  - 🏠 **100% HF-Native:** Runs entirely on HuggingFace’s free infrastructure (2 vCPU, 16GB RAM).
83
 
84
  ## πŸŽ₯ Video Tutorial
@@ -104,7 +104,9 @@ Navigate to your new Space's **Settings**, scroll down to the **Variables and se
104
  > [!TIP]
105
  > HuggingClaw is completely flexible! You only need these three secrets to get started. You can set other secrets later.
106
 
107
- Optional: set `DEV_MODE=true` (Variable) to enable JupyterLab support and install Jupyter dependencies at build time. You can also set `JUPYTER_TOKEN` as a Secret to replace the default terminal token (`huggingface`). If you want to pin a specific OpenClaw release instead of `latest`, add `OPENCLAW_VERSION` under **Variables** in your Space settings. For Docker Spaces, HF passes Variables as build args during image build, so these should be Variables, not Secrets (except tokens).
 
 
108
 
109
  ### Step 3: Deploy & Run
110
 
@@ -366,12 +368,12 @@ The merged Space includes the Hugging Face JupyterLab template behavior inside t
366
  | :--- | :--- | :--- | :--- |
367
  | `/` | HuggingClaw dashboard | `7861` | Public HF Spaces entrypoint |
368
  | `/app/` | OpenClaw Control UI | `7860` | Mounted behind the local reverse proxy |
369
- | `/terminal/` | JupyterLab terminal (DEV_MODE only) | `8888` | Available only when `DEV_MODE=true`; token login uses `JUPYTER_TOKEN` (default `huggingface`) |
370
 
371
  When enabled, the terminal notebook root is `/home/node`, so you can inspect HuggingClaw files, logs, workspace state, and runtime scripts from the browser.
372
 
373
  > [!IMPORTANT]
374
- > For real deployments, set a strong `JUPYTER_TOKEN` secret. The `huggingface` default exists only to match the duplicateable Hugging Face JupyterLab template.
375
 
376
  ## πŸ” Merge Comparison
377
 
 
20
  - name: GATEWAY_TOKEN
21
  description: "Strong token to secure your OpenClaw Control UI (generate: openssl rand -hex 32)."
22
  - name: JUPYTER_TOKEN
23
+ description: "Optional token for the JupyterLab terminal at /terminal/. Defaults to GATEWAY_TOKEN when set β€” no extra secret needed."
24
  - name: CLOUDFLARE_WORKERS_TOKEN
25
  description: "Cloudflare API token β€” auto-creates a Worker proxy and KeepAlive monitor."
26
  - name: TELEGRAM_ALLOWED_USERS
 
78
  - πŸ“Š **Visual Dashboard:** Beautiful Web UI to monitor uptime, sync status, and active models.
79
  - πŸ”” **Webhooks:** Get notified on restarts or backup failures via standard webhooks.
80
  - πŸ” **Flexible Auth:** Secure the Control UI with either a gateway token or password.
81
+ - πŸ’» **Terminal Out of the Box:** JupyterLab is available at `/terminal/` automatically when `GATEWAY_TOKEN` is set β€” no extra config needed. `GATEWAY_TOKEN` is reused as the terminal auth token. Set `DEV_MODE=false` explicitly to opt out.
82
  - 🏠 **100% HF-Native:** Runs entirely on HuggingFace’s free infrastructure (2 vCPU, 16GB RAM).
83
 
84
  ## πŸŽ₯ Video Tutorial
 
104
  > [!TIP]
105
  > HuggingClaw is completely flexible! You only need these three secrets to get started. You can set other secrets later.
106
 
107
+ **Terminal auto-enables when `GATEWAY_TOKEN` is set** β€” no extra secrets needed. `GATEWAY_TOKEN` is reused as `JUPYTER_TOKEN`, so the terminal is protected by the same credential as the Control UI. To set a different token, add `JUPYTER_TOKEN` as a Secret. To disable the terminal entirely, set `DEV_MODE=false` as a Variable.
108
+
109
+ If you want to pin a specific OpenClaw release instead of `latest`, add `OPENCLAW_VERSION` under **Variables** in your Space settings. For Docker Spaces, HF passes Variables as build args during image build, so these should be Variables, not Secrets (except tokens).
110
 
111
  ### Step 3: Deploy & Run
112
 
 
368
  | :--- | :--- | :--- | :--- |
369
  | `/` | HuggingClaw dashboard | `7861` | Public HF Spaces entrypoint |
370
  | `/app/` | OpenClaw Control UI | `7860` | Mounted behind the local reverse proxy |
371
+ | `/terminal/` | JupyterLab terminal | `8888` | Auto-enabled when `GATEWAY_TOKEN` is set; uses `GATEWAY_TOKEN` as auth token unless `JUPYTER_TOKEN` is set separately. Set `DEV_MODE=false` to disable. |
372
 
373
  When enabled, the terminal notebook root is `/home/node`, so you can inspect HuggingClaw files, logs, workspace state, and runtime scripts from the browser.
374
 
375
  > [!IMPORTANT]
376
+ > No extra secret needed β€” `GATEWAY_TOKEN` is automatically reused as `JUPYTER_TOKEN`. Set a separate `JUPYTER_TOKEN` secret only if you want a different terminal credential.
377
 
378
  ## πŸ” Merge Comparison
379
 
health-server.js CHANGED
@@ -20,9 +20,12 @@ const GATEWAY_HOST = "127.0.0.1";
20
  const JUPYTER_PORT = Number.parseInt(process.env.JUPYTER_PORT || "8888", 10);
21
  const JUPYTER_HOST = "127.0.0.1";
22
  const JUPYTER_BASE = normalizeBase(process.env.JUPYTER_BASE, "/terminal");
 
23
  const DEV_MODE_ENABLED = isTrue(process.env.DEV_MODE);
 
 
24
  const JUPYTER_ENABLED = /^(true|1|yes|on)$/i.test(
25
- process.env.HUGGINGCLAW_JUPYTER_ENABLED || (DEV_MODE_ENABLED ? "true" : "false")
26
  );
27
  const startTime = Date.now();
28
  const LLM_MODEL = process.env.LLM_MODEL || "Not Set";
 
20
  const JUPYTER_PORT = Number.parseInt(process.env.JUPYTER_PORT || "8888", 10);
21
  const JUPYTER_HOST = "127.0.0.1";
22
  const JUPYTER_BASE = normalizeBase(process.env.JUPYTER_BASE, "/terminal");
23
+ const GATEWAY_TOKEN = (process.env.GATEWAY_TOKEN || "").trim();
24
  const DEV_MODE_ENABLED = isTrue(process.env.DEV_MODE);
25
+ // Auto-enable Jupyter when DEV_MODE=true, HUGGINGCLAW_JUPYTER_ENABLED=true, or GATEWAY_TOKEN is set.
26
+ // GATEWAY_TOKEN doubles as JUPYTER_TOKEN in start.sh β€” no extra secret needed.
27
  const JUPYTER_ENABLED = /^(true|1|yes|on)$/i.test(
28
+ process.env.HUGGINGCLAW_JUPYTER_ENABLED || (DEV_MODE_ENABLED ? "true" : GATEWAY_TOKEN ? "true" : "false")
29
  );
30
  const startTime = Date.now();
31
  const LLM_MODEL = process.env.LLM_MODEL || "Not Set";
start.sh CHANGED
@@ -90,6 +90,12 @@ DEV_MODE_ENABLED=false
90
  if hc_is_true "$DEV_MODE_NORMALIZED"; then
91
  DEV_MODE_ENABLED=true
92
  fi
 
 
 
 
 
 
93
  SYNC_INTERVAL="$(trim_var "${SYNC_INTERVAL:-180}")"
94
  DEVDATA_DATASET_NAME="$(trim_var "${DEVDATA_DATASET_NAME:-huggingclaw-devdata}")"
95
  DEVDATA_SYNC_INTERVAL="$(trim_var "${DEVDATA_SYNC_INTERVAL:-180}")"
@@ -848,6 +854,13 @@ start_jupyter_once() {
848
  return 0
849
  fi
850
 
 
 
 
 
 
 
 
851
  # Security guard: refuse to start JupyterLab with the insecure default token.
852
  # JupyterLab exposes a full shell β€” a weak token is equivalent to no auth.
853
  if [ -z "${JUPYTER_TOKEN:-}" ] || [ "${JUPYTER_TOKEN}" = "huggingface" ]; then
 
90
  if hc_is_true "$DEV_MODE_NORMALIZED"; then
91
  DEV_MODE_ENABLED=true
92
  fi
93
+ # Auto-enable DEV_MODE when GATEWAY_TOKEN is set and DEV_MODE was not explicitly configured.
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}")"
101
  DEVDATA_SYNC_INTERVAL="$(trim_var "${DEVDATA_SYNC_INTERVAL:-180}")"
 
854
  return 0
855
  fi
856
 
857
+ # GATEWAY_TOKEN fallback: if JUPYTER_TOKEN is unset or still the insecure default,
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.
865
  # JupyterLab exposes a full shell β€” a weak token is equivalent to no auth.
866
  if [ -z "${JUPYTER_TOKEN:-}" ] || [ "${JUPYTER_TOKEN}" = "huggingface" ]; then