openvibers/openvibe.codes Commits

Codes: a task's repository heading breaks only after a slash; a stream that cannot open reloads every 15 s (#64)

OP OpenVibers committed 30 days ago · c8cfb73a7b · 3 files, +14 −4

Two things seen on the first real task on production (a phone, octocat/Hello-World run on the owner's own machine):

- **The heading broke mid-word** ("github.com/octocat/Hell" then "o-World"). The host now sits small above `owner/name`, which may break only after a slash. The task list shows the same.
- **A stream that cannot open** (Run busy or down) reloaded the page every 3 s. It now reloads every 15 s. Until today Run's stream tickets were off on production (its key file sat in a directory its user cannot read; fixed on the host), so every open task page did this.

**Tests:** `run-pages` passes.

Changes

ddiff --git a/public/css/run.css b/public/css/run.css
iindex 5e6bbfa..35decc2 100644
---- a/public/css/run.css
++++ b/public/css/run.css
@@@ -31,3 +31,5 @@
.run-patch .add { color: var(--success, #22c55e); }
.run-patch .del { color: var(--danger, #e5484d); }
.run-patch .hunk { color: var(--accent-light, #60a5fa); }
++.run-repo { overflow-wrap: break-word; }
++.run-host { display: block; font-size: 0.55em; font-weight: 500; color: var(--text-muted, #8b9bb4); }
ddiff --git a/public/js/run.js b/public/js/run.js
iindex 8f8497e..ba2755b 100644
---- a/public/js/run.js
++++ b/public/js/run.js
@@@ -60,8 +60,9 @@
setTimeout(function () { window.location.reload(); }, 800);
});
source.onerror = function () {
-- // The stream ended or the link dropped: the page itself shows where the task is.
-- if (source.readyState === 2) setTimeout(function () { window.location.reload(); }, 3000);
++ // The stream ended or could not open (Run busy or down): the page itself shows where the task is, so it is
++ // reloaded, not too often while the stream stays away.
++ if (source.readyState === 2) setTimeout(function () { window.location.reload(); }, 15000);
};
}
ddiff --git a/server/http/run.js b/server/http/run.js
iindex 472f3e9..847c62e 100644
---- a/server/http/run.js
++++ b/server/http/run.js
@@@ -16,6 +16,13 @@ const express = require('express');
const { asyncRouter } = require('./router');
const { send } = require('../render/layout');
const { html, raw, esc } = require('../render/html');
++
++/** A repository URL as a heading: the host small, then owner/name, which may break after a slash but never mid-word. */
++function repoName(url) {
++ const [host, ...path] = String(url).replace(/^https:\/\//, '').split('/');
++ if (!path.length) return host;
++ return html`<small class="run-host">${host}/</small>${path.map((part, i) => html`${i ? raw('/<wbr>') : ''}${part}`)}`;
++}
const { parseArgs } = require('../../harness/job');
const { RunError } = require('../domain/run-client');
@@@ -90,7 +97,7 @@ ${error ? html`<p class="run-notice run-notice-error" role="alert">${error}</p>`
function tasksHtml(rows) {
if (!rows.length) return html`<p class="muted">No tasks yet.</p>`;
-- return html`<ul class="run-tasks">${rows.map((t) => html`<li><a href="/run/tasks/${t.id}"><span class="run-pill run-pill-${t.state}">${STATE_LABEL[t.state] || t.state}</span> <b>${t.repo.replace(/^https:\/\//, '')}</b> <span class="muted">${t.prompt.split('\n')[0].slice(0, 90)}</span></a></li>`)}</ul>`;
++ return html`<ul class="run-tasks">${rows.map((t) => html`<li><a href="/run/tasks/${t.id}"><span class="run-pill run-pill-${t.state}">${STATE_LABEL[t.state] || t.state}</span> <b>${repoName(t.repo)}</b> <span class="muted">${t.prompt.split('\n')[0].slice(0, 90)}</span></a></li>`)}</ul>`;
}
async function runPage(req, res, { values, error, status = 200 } = {}) {
@@@ -200,7 +207,7 @@ ${typeof d.duration_ms === 'number' ? html`<p class="muted">${Math.round(d.durat
row = await refresh(row);
const live = !TERMINAL.has(row.state);
const body = html`<p class="crumbs"><a href="/run">Run on your machine</a></p>
--<h1>${row.repo.replace(/^https:\/\//, '')}${row.ref ? html` <small>${row.ref}</small>` : ''}</h1>
++<h1 class="run-repo">${repoName(row.repo)}${row.ref ? html` <small>${row.ref}</small>` : ''}</h1>
<p><span class="run-pill run-pill-${row.state}" data-state>${STATE_LABEL[row.state] || row.state}</span>${row.agent ? html` <span class="run-pill">${row.agent}</span>` : ''}</p>
<pre class="run-prompt">${row.prompt}</pre>
${live ? html`<section class="run-live" data-events="/run/tasks/${row.id}/events" aria-live="polite"><h2>Live</h2><ol class="run-log" data-log></ol></section>