openvibers/openvibe.bot Commits

Bot directory: the simulated rover is always the first card (#131)

OP OpenVibers committed 28 days ago · 874c820d0c · 3 files, +10 −4

* Bot directory: the simulated rover is always the first robot to drive (no more "No robot is listed yet")

* Bot STATUS: dated 2026-10-16 (package.json changed today)

Changes

ddiff --git a/STATUS.json b/STATUS.json
iindex a99d7f8..6cc41d0 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -61,5 +61,5 @@
"server-side ONVIF cameras (profile camera.onvif, driver onvif, server/onvif): an in-process device beside the simulator attaches a camera configured with BOT_ONVIF_CAMERAS (its URL plus username_ref/password_ref secret references, never in the profile or in clear), writes a real kind server device row, translates ptz commands to ONVIF ContinuousMove/Stop with the profile deadline as a deadman, and carries the camera's GetStatus readout in telemetry; every request goes only to the configured host, with a timeout and no redirects",
"a person's own machines that run their jobs (/machines: add with a --worker command, list, remove); their worker offers reported to Network as user-owned offers naming the owner; jobs reach a machine only for its owner (plan T14/T16)"
],
-- "updated": "2026-10-15"
++ "updated": "2026-10-16"
}
ddiff --git a/server/web/directory.js b/server/web/directory.js
iindex f2fd196..980a2fd 100644
---- a/server/web/directory.js
++++ b/server/web/directory.js
@@@ -138,6 +138,12 @@ function robotCard(r) {
+ `<p class="dir-card-foot">${esc(POLICY_WORDS[r.access_policy] || '')}</p></li>`;
}
++// The simulated rover anyone can drive (/try): always the first card, so the directory shows a robot to drive today.
++const DEMO_CARD = '<li class="dir-card"><a class="dir-card-link" href="/try"><span class="dir-card-head"><b>Simulated rover</b>'
++ + '<span class="dir-state" data-state="online"><span class="dir-dot"></span>Online</span></span>'
++ + '<span class="dir-card-text">Runs in your browser · OpenVibe.Bot</span></a>'
++ + '<p class="dir-card-foot">Anyone can drive it, no account needed</p></li>';
++
// ── GET /robots ─────────────────────────────────────────────────────────────────────────────────────
function renderDirectory({ config, listed = [], mine = null, models = [], signedIn = false }) {
const yours = !signedIn ? `<section class="dir-sec dir-cta"><h2>Have a robot?</h2>
@@@ -152,8 +158,8 @@ ${mine && mine.length ? `<ul class="dir-list">${mine.map((r) => `<li class="dir-
<p class="muted">Robots people share on OpenVibe.Bot, and every model it drives. Watch any listed robot live; some take visitors at the controls in turns.</p></header>
${yours}
<section class="dir-sec" aria-labelledby="listed-h"><h2 id="listed-h">In the directory</h2>
--${listed.length ? `<ul class="dir-grid">${listed.map(robotCard).join('')}</ul>`
-- : `<p class="muted">No robot is listed yet. An owner lists theirs from its panel (Directory), and it shows here with its live camera.</p>`}</section>
++<ul class="dir-grid">${DEMO_CARD}${listed.map(robotCard).join('')}</ul>
++${listed.length ? '' : '<p class="muted">Owners list their robots from the panel (Directory), and each shows here with its live camera.</p>'}</section>
<section class="dir-sec" aria-labelledby="models-h"><div class="dir-sec-head"><h2 id="models-h">Models it drives</h2>${link('/models', 'All models')}</div>
<ul class="dir-grid">${sortModels(models).map(modelCard).join('')}</ul></section>
<section class="dir-sec" aria-labelledby="byo-h"><h2 id="byo-h">Something else?</h2>
ddiff --git a/test/directory.test.js b/test/directory.test.js
iindex d03393f..667f916 100644
---- a/test/directory.test.js
++++ b/test/directory.test.js
@@@ -28,7 +28,7 @@ const { loadProfiles } = require('../server/profiles');
for (const p of profiles) assert.ok(html.includes(`href="/models/${p.id}"`), p.id);
assert.ok(html.includes('href="/try"') && html.includes('Sign in and add a robot'));
assert.ok(!html.includes('Your robots') && !html.includes('Garage rover'), 'an unlisted robot is nobody else\'s business');
-- assert.ok(html.includes('No robot is listed yet.'));
++ assert.ok(html.includes('<a class="dir-card-link" href="/try"><span class="dir-card-head"><b>Simulated rover</b>'), 'the simulated rover is always the first robot to drive');
});
await check('signed in: your robots, each marked listed or not, and Add a robot', async () => {