Compare commits

...
2 Commits
Author SHA1 Message Date
Gmer4Lfe 4b6c5fe1cc Bring the docs up to the chat window we actually built
The readmes still described a single expand glyph and a chevron for saved chats, and neither knew
about the banner, the two expanded sizes or the shortcuts list.
2026-08-09 13:45:30 -04:00
Gmer4Lfe 66f9d6f435 Count orchestrators on the board, pin it, and open on the assistant
Counting every step reported a fully scheduled system as 10 of 82, and reopening the last thread
brought its profile with it, so the tab came up as Troubleshoot pointed at nothing.
2026-08-09 13:41:53 -04:00
5 changed files with 73 additions and 18 deletions
+14 -2
View File
@@ -128,8 +128,20 @@ composed from a prefix so instances can coexist, and each tears down the previou
prefix, because Unraid swaps tab content by AJAX without unloading the old page's JavaScript.
A placement chooses how much room it gets and which extra controls it needs. It does not choose
the shape: the control row is fixed everywhere — profile chip hard left, `⤢` `▾` `New` `Ask` hard
right — because a chat that rearranges itself per tab is three components wearing one name.
the shape, because a chat that rearranges itself per tab is three components wearing one name.
The layout is fixed everywhere:
- **Banner** — title, then `Medium`/`Large` and `Shortcuts` at the right.
- **Transcript**.
- **Composer**, then one row grouped by what each control acts on: the profile chip at the left
for what is *answering*, `New` `Saved` `Ask` centred for what you do to the *conversation*, `⤢`
at the right for what you do to the *window*.
`⤢` and `Medium`/`Large` are deliberately separate: whether the conversation is expanded is an
action taken constantly, how much expanded is worth is a preference set once. The shortcuts list
is subtracted from the transcript rather than added above it, so opening it never changes the
window's total height — which matters on the Scheduler, where that height is a fixed share of a
panel that clips.
The Scheduler panel was exactly that until it was folded in, and it proved the cost: a thread
there died on reload while the other two were saved, and its bar had drifted into a different
+11 -4
View File
@@ -739,10 +739,14 @@ body.vv-fullscreen #displaybox { padding-left: 1rem !important; padding-top: .5r
.vv-info-divider { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: #444;
padding: 10px 12px 4px; border-top: 1px solid #2a2a2a; margin-top: 2px; }
/* How do I use this — pinned at top of suggestions panel */
/* How do I use this — pinned directly beneath the notification board.
top is the board's measured height, not a constant: the board wraps to a second line in
Advanced mode, where the conf buttons and Git Pull join it. A hardcoded offset would let this
slide underneath it at exactly the width where the wrap happens. vvFitRight() keeps the
variable in step; the fallback is the board's own min-height. */
#vv-how-to-use {
position: sticky;
top: 0;
top: var(--vv-nb-h, 34px);
z-index: 3;
background: #1e1e1e;
border-bottom: 1px solid #333;
@@ -873,10 +877,13 @@ mark { background: #5d4037; color: #ffcc80; border-radius: 2px; }
.vv-disabled-name { color: #888; flex: 1; }
.vv-disabled-grp { color: #444; font-size: 10px; font-family: monospace; white-space: nowrap; }
/* Notification board */
/* Notification board. Pinned above the help block: what is running and what is scheduled is the
one thing on this panel worth seeing while reading anything else on it. Highest z-index of the
two pinned rows because it is the topmost — #vv-how-to-use sticks directly beneath it. */
.vv-nb-board { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
padding: 7px 10px; background: #141414; border-bottom: 1px solid #222;
font-size: 12px; min-height: 34px; }
font-size: 12px; min-height: 34px;
position: sticky; top: 0; z-index: 4; }
.vv-nb-stat { color: #aaa; }
.vv-nb-sep { color: #444; }
.vv-nb-running { color: #f0a040; }
+4 -2
View File
@@ -61,8 +61,10 @@ as the GPU and UPS cards.
| Conversations | The last `$AI_CHAT_HISTORY_MAX` chats. Click to reopen, × to delete |
| Assistant | Ask a question without leaving the dashboard |
| Profile chip | Which contract answers — General Chat, Varaverk Assistant, Code Sketcher, Troubleshoot |
| ⤢ | Trades more room for the conversation, and back. Always opens at the smaller size |
| ▾ | Saved conversations, the same ones the Conversations card lists |
| ⤢ | Expands the conversation, and collapses it again. Always opens collapsed |
| Medium / Large | In the banner, once expanded — how much room expanding is worth |
| Shortcuts | In the banner — the keyboard list, paid for out of the transcript rather than added to it |
| Saved | Saved conversations, the same ones the Conversations card lists |
---
+12 -3
View File
@@ -176,8 +176,10 @@ on disk is never touched until you press Save.
| **+ Folder** | Custom Scripts | A collapsible subfolder you can drag scripts into |
| **why? / recap** | Recent Activity | Opens that run's log and asks the assistant about it in one click |
| **Profile chip** | Assistant | What is answering, and what it is pointed at. Click to change the profile |
| **⤢** | Assistant | Trades more of the panel for the conversation, and back |
| **** | Assistant | Saved conversations, shared with the AI tab and the Monitor dashboard |
| **⤢** | Assistant | Expands the conversation into the panel, and collapses it again |
| **Medium / Large** | Assistant banner | How much of the panel expanding is worth — 20% or 40% |
| **Shortcuts** | Assistant banner | The keyboard list. Taken out of the transcript, so the panel keeps its height |
| **Saved** | Assistant | Saved conversations, shared with the AI tab and the Monitor dashboard |
| **New** | Assistant | Starts a fresh conversation; the old one stays in the store |
## Reference — orchestrator and step behaviour
@@ -197,11 +199,18 @@ on disk is never touched until you press Save.
The right-hand panel is the default view and everything returns to it. **← Scheduler Info** comes
back here from any log, editor, conf form or script view.
- **Notification board** — how many jobs are scheduled out of the total, and what is running now.
- **Notification board** — how many orchestrators are scheduled, how many scripts carry a cron of
their own, and what is running now. Pinned, so it stays visible while you read the rest.
- **Next Runs** — what fires next, and when.
- **Recent Activity** / **Recent Errors** — described above.
- **Cron Calculator** — described above.
The board counts **orchestrators**, not scripts. A schedule here is normally one cron on an
orchestrator that then calls its steps in order, so the steps are deliberately cronless — counting
them made a fully-scheduled system read as `10 / 82 scheduled`, which is alarming and wrong. Steps
that *do* carry their own cron are counted separately as standalone, because that is the exception
and the number of exceptions is the figure worth knowing. It shows only when there are any.
## Reference — Advanced mode
The **Advanced** button at the top right turns blue when active. It is a display and editing
+32 -7
View File
@@ -137,14 +137,22 @@ $_childManuals = array_values(array_filter($_repoFiles, function($f) {
}));
sort($_childManuals);
// Job stats for notification board
$totalJobs = 0; $scheduledJobs = 0;
// Job stats for notification board.
//
// Counted against orchestrators, not against every script. A schedule here is normally expressed
// as one cron on an orchestrator that then calls its steps in order, so the steps are deliberately
// cronless — counting them as unscheduled reported a fully-scheduled system as almost entirely
// unscheduled, "10 / 82", which is alarming and wrong.
//
// Steps that do carry their own cron are counted separately. That happens when an orchestrator is
// off and its steps have been given schedules of their own, which is the exception — and the
// number of exceptions is the figure actually worth knowing.
$orchTotal = 0; $orchScheduled = 0; $soloScheduled = 0;
foreach ($tree as $orch) {
$totalJobs++;
if (!empty($orch['cron']) && $orch['enabled']) $scheduledJobs++;
$orchTotal++;
if (!empty($orch['cron']) && $orch['enabled']) $orchScheduled++;
foreach (($orch['children'] ?? []) as $child) {
$totalJobs++;
if (!empty($child['cron']) && $child['enabled']) $scheduledJobs++;
if (!empty($child['cron']) && $child['enabled']) $soloScheduled++;
}
}
$runningScripts = [];
@@ -493,7 +501,11 @@ $runningScripts = array_unique($runningScripts);
<!-- ── Notification Board ── -->
<div class="vv-nb-board">
<span class="vv-nb-stat"><?= $scheduledJobs ?> / <?= $totalJobs ?> scheduled</span>
<span class="vv-nb-stat"><?= $orchScheduled ?> / <?= $orchTotal ?> orchestrators</span>
<?php if ($soloScheduled): ?>
<span class="vv-nb-sep">·</span>
<span class="vv-nb-stat"><?= $soloScheduled ?> standalone<?= $soloScheduled === 1 ? '' : 's' ?></span>
<?php endif; ?>
<span class="vv-nb-sep">·</span>
<span class="vv-nb-stat <?= !empty($runningScripts) ? 'vv-nb-running' : '' ?>">
<?= !empty($runningScripts) ? 'Running: ' . htmlspecialchars(implode(', ', $runningScripts)) : 'Idle' ?>
@@ -1203,6 +1215,12 @@ function vvFitRight() {
const pre = document.getElementById('vv-log-pre');
const sug = document.getElementById('vv-suggestions');
// The pinned help block sticks directly under the notification board, so it needs the board's
// real height — which changes when Advanced mode adds the conf buttons and the board wraps.
// Set before the stacked-layout return below, because the two rows stay pinned there too.
const nb = right.querySelector('.vv-nb-board');
if (nb && sug) sug.style.setProperty('--vv-nb-h', nb.offsetHeight + 'px');
const leftRect = left.getBoundingClientRect();
const rightRect = right.getBoundingClientRect();
@@ -2398,6 +2416,13 @@ if (document.getElementById('vv-sched-ai-chat')) {
prefix: 'vv-sched-ai',
profile: vvAiProfile,
scopeLabel: vvAiScopeLabel,
// No reopening the last thread here, unlike the other two surfaces. Restoring a conversation
// restores the profile it was held under, so the tab would come up as Troubleshoot pointed at
// a log nobody has opened — the chip saying one thing and vvAiScope saying "Scheduler". This
// panel's subject follows the view, and at load the view is the tab itself, so it starts where
// that puts it: the assistant, scoped to the Scheduler. Saved threads are a click away under
// Saved.
resume: false,
// Re-read at send time rather than captured, because the operator moves around this tab
// between asking and sending.
scope: () => vvAiScope,