fix(cron): surface gateway scheduling guidance

This commit is contained in:
Frank Song
2026-05-24 19:55:39 +08:00
committed by nesquena-hermes
parent 67a204773e
commit f1586daa3b
5 changed files with 81 additions and 0 deletions

View File

@@ -46,6 +46,13 @@ That's it for a real personal Docker install. Your existing `~/.hermes`
directory is mounted, your `~/workspace` is browsable, and the WebUI
auto-detects your UID/GID from the mounted volume.
The single-container setup runs the WebUI only. It can create cron jobs and run
them manually from the Tasks panel. In Docker, scheduled jobs require the Hermes gateway daemon
to tick while you are away. If System Settings shows `Gateway not configured`,
use `docker-compose.two-container.yml`,
`docker-compose.three-container.yml`, or run `hermes gateway` separately before
relying on offline scheduled runs.
For troubleshooting, reinstall, or onboarding reproduction trials, do not mount
your real `~/.hermes` unless you intentionally want to test real state. Use an
isolated Hermes home and follow

View File

@@ -205,6 +205,7 @@
<button class="panel-head-btn has-tooltip has-tooltip--bottom" onclick="openCronCreate()" data-tooltip="New job" data-i18n-title="new_job" aria-label="New job"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg></button>
</div>
</div>
<div id="cronGatewayNotice" class="detail-alert cron-gateway-notice" style="display:none"></div>
<div class="cron-list" id="cronList"><div style="padding:12px;color:var(--muted);font-size:12px" data-i18n="loading">Loading...</div></div>
</div>
<!-- Kanban panel -->

View File

@@ -428,9 +428,44 @@ function _cronDiagnostics(job) {
return JSON.stringify(fields, null, 2);
}
function _cronGatewayNoticeHtml(status) {
if (!status || (status.configured && status.running)) return '';
const notConfigured = !status.configured;
const title = notConfigured
? 'Gateway not configured'
: 'Gateway not running';
const body = notConfigured
? 'In Hermes WebUI, scheduled jobs require the Hermes gateway daemon. If this is a single-container Docker install, jobs can be created and run manually here, but scheduled ticks need a gateway container or `hermes gateway` running outside the WebUI.'
: 'In Hermes WebUI, scheduled jobs require the Hermes gateway daemon to be running. Start the gateway container or `hermes gateway` before relying on offline scheduled runs.';
return `
<div class="detail-alert-title">${esc(title)}</div>
<p>${esc(body)}</p>
`;
}
async function loadCronGatewayNotice() {
const box = $('cronGatewayNotice');
if (!box) return;
try {
const status = await api('/api/gateway/status');
const html = _cronGatewayNoticeHtml(status);
if (html) {
box.innerHTML = html;
box.style.display = '';
} else {
box.innerHTML = '';
box.style.display = 'none';
}
} catch (_) {
box.innerHTML = '';
box.style.display = 'none';
}
}
async function loadCrons(animate) {
const box = $('cronList');
const refreshBtn = $('cronRefreshBtn');
loadCronGatewayNotice();
if (animate && refreshBtn) {
refreshBtn.style.opacity = '0.5';
refreshBtn.disabled = true;

View File

@@ -1109,6 +1109,7 @@
.panel-view.active{display:flex;}
/* Cron panel */
.cron-list{flex:1;overflow-y:auto;padding:8px;}
.cron-gateway-notice{margin:8px 8px 0;}
.cron-item{width:100%;min-width:0;box-sizing:border-box;border-radius:10px;border:1px solid var(--border);margin-bottom:6px;overflow:hidden;transition:border-color .15s,background .15s;background:rgba(255,255,255,.02);cursor:pointer;}
.cron-item:hover{border-color:var(--border2);}
.cron-header{display:flex;align-items:center;gap:8px;padding:10px 12px;cursor:pointer;}

View File

@@ -0,0 +1,37 @@
"""Coverage for cron/gateway guidance in the Tasks panel and Docker docs."""
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
INDEX_HTML = ROOT / "static" / "index.html"
PANELS_JS = ROOT / "static" / "panels.js"
DOCKER_DOC = ROOT / "docs" / "docker.md"
def test_tasks_panel_has_gateway_notice_container():
html = INDEX_HTML.read_text(encoding="utf-8")
assert 'id="cronGatewayNotice"' in html
assert "detail-alert" in html
def test_cron_panel_loads_gateway_status_for_scheduling_guidance():
panels = PANELS_JS.read_text(encoding="utf-8")
assert "function _cronGatewayNoticeHtml" in panels
assert "function loadCronGatewayNotice" in panels
assert "api('/api/gateway/status')" in panels
assert "Gateway not configured" in panels
assert "Gateway not running" in panels
assert "scheduled jobs require the Hermes gateway daemon" in panels
assert "loadCronGatewayNotice()" in panels
def test_docker_docs_explain_single_container_cron_gateway_boundary():
docs = DOCKER_DOC.read_text(encoding="utf-8")
assert "single-container setup runs the WebUI only" in docs
assert "scheduled jobs require the Hermes gateway daemon" in docs
assert "Gateway not configured" in docs
assert "docker-compose.two-container.yml" in docs