diff --git a/TODO.md b/TODO.md index 3cb73324..3933ba53 100644 --- a/TODO.md +++ b/TODO.md @@ -57,41 +57,22 @@ Pick anything from here when relevant. Cross-cutting design notes live in Repro: manager calls `ask_operator`, tool result is `question queued (id=N)` (so the row is in sqlite), but the M1ND H4S QU3STI0NS section keeps showing "no pending - questions". Last seen with id=5. Diagnostic step landed: - `api_state` now warn-logs (target=`api_state`) when any of - its source queries fail instead of silently - `unwrap_or_default`-ing — next repro should print the - underlying error in journald and tell us whether this is - sqlite (likely `OperatorQuestions::pending()` row-decode - panic on a migrated column) or dashboard-JS-side - (`renderQuestions` exception). Re-investigate with the new - log once the bug fires. + questions". Last seen with id=5. Suspected paths: + - `OperatorQuestions::pending()` returns Err and the + `unwrap_or_default()` in `api_state` hides it. Surface the + error (warn-log) and check. + - serialization: a new field in `OpQuestion` (e.g. + `deadline_at: Option`) deserializes wrong against an + old row whose columns don't match the new SELECT order → + `row.get(N)?` panics for that row, the whole iterator + errors, `pending()` returns Err. Diagnose by curl + `/api/state | jq '.questions'` and compare with sqlite + counts. + - dashboard JS swallows a render error. Open browser console + and look for exceptions during `renderQuestions`. ## UI / UX -- **Dashboard layout overhaul.** A 3-column attempt (swarm - / 0per4t0r 1n / m3ss4g3s) landed + was reverted in 74ba8a6 - — looked worse in practice (sticky col-heads fighting the - banner, sub-heads too small, columns too narrow for the - container rows). Sections are now ordered semantically in - a single column (swarm bits first, then decisions, then - messages) which is a no-cost improvement. The bigger - restructure is still worth doing; next attempt should: - - keep current widths usable (don't crunch container - rows < ~36em — they have a lot inline) - - default the heavy-but-rare sections (kept-state, meta- - inputs, msg-flow history) into a collapsed `
` - so they don't dominate when empty - - drop the per-section banner divider lines in favour of - something quieter (a single border-top on the h2?) - - try a *masonry-ish* layout (CSS `grid-template-rows: - masonry` once browsers support it; or just two columns - where messages floats on the right at wide viewports - while the rest stacks left). avoid sticky headers — they - fought the page banner last time. - - - - **Web UI for config repos + meta deploy log.** Browse per-agent proposed / applied tags (`proposal/* / approved/* / building/* / deployed/* / diff --git a/hive-c0re/assets/app.js b/hive-c0re/assets/app.js index 7b075c03..293f087d 100644 --- a/hive-c0re/assets/app.js +++ b/hive-c0re/assets/app.js @@ -606,23 +606,6 @@ const root = $('approvals-section'); root.innerHTML = ''; - // Spawn request form: submitting it queues a Spawn approval that - // lands in this same list, so the form belongs here rather than on - // the containers list (the agent doesn't exist yet). - const spawn = el('form', { - method: 'POST', action: '/request-spawn', - class: 'spawnform', 'data-async': '', - }); - spawn.append( - el('input', { - name: 'name', - placeholder: 'new agent name (≤9 chars)', - maxlength: '9', required: '', autocomplete: 'off', - }), - el('button', { type: 'submit', class: 'btn btn-spawn' }, '◆ R3QU3ST SP4WN'), - ); - root.append(spawn); - const history = s.approval_history || []; const active = localStorage.getItem(APPROVAL_TAB_KEY) || 'pending'; const tabs = el('div', { class: 'approval-tabs' }); diff --git a/hive-c0re/assets/dashboard.css b/hive-c0re/assets/dashboard.css index 27269eb1..bbbe441e 100644 --- a/hive-c0re/assets/dashboard.css +++ b/hive-c0re/assets/dashboard.css @@ -18,11 +18,50 @@ body { background: var(--bg); color: var(--fg); font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", "Source Code Pro", monospace; - max-width: 70em; + max-width: 110em; margin: 1.5em auto; padding: 0 1.5em; line-height: 1.6; } +.columns { + display: grid; + gap: 1.4em; + margin-top: 1em; +} +@media (min-width: 1400px) { + .columns { + grid-template-columns: 1.1fr 1fr 1fr; + align-items: start; + } +} +.dash-col { + min-width: 0; /* lets grid children shrink instead of overflowing */ +} +.col-head { + position: sticky; + top: 0; + z-index: 5; + background: rgba(30, 30, 46, 0.92); + -webkit-backdrop-filter: blur(6px); + backdrop-filter: blur(6px); + margin: 0 0 0.6em; + padding: 0.3em 0.5em; + font-size: 1em; + border-bottom: 1px solid var(--purple-dim); +} +.sub-head { + color: var(--cyan); + font-size: 0.85em; + letter-spacing: 0.12em; + text-transform: uppercase; + margin: 1.6em 0 0.4em; + padding-bottom: 0.15em; + border-bottom: 1px dashed var(--border, var(--purple-dim)); + text-shadow: 0 0 6px rgba(137, 220, 235, 0.35); +} +.dash-col .sub-head:first-of-type { + margin-top: 0.4em; +} .banner { text-align: center; margin: 0 0 1em 0; @@ -52,7 +91,7 @@ h1, h2 { color: var(--purple); text-transform: uppercase; letter-spacing: 0.15em; - margin-top: 2em; + margin-top: 1em; text-shadow: 0 0 8px rgba(203, 166, 247, 0.4); } .divider { diff --git a/hive-c0re/assets/index.html b/hive-c0re/assets/index.html index 6af8ef76..d154610e 100644 --- a/hive-c0re/assets/index.html +++ b/hive-c0re/assets/index.html @@ -17,57 +17,83 @@ - -

◆ C0NTAINERS ◆

-
══════════════════════════════════════════════════════════════
-
-

loading…

-
+
+ +
+

◆ SW4RM ◆

-

◆ K3PT ST4T3 ◆

-
══════════════════════════════════════════════════════════════
-
-

loading…

-
+

containers

+
+

loading…

+
-

◆ M3T4 1NPUTS ◆

-
══════════════════════════════════════════════════════════════
-

select inputs to nix flake update in /meta/. selected agents rebuild in sequence after the lock bump; manager learns each outcome via the usual rebuilt system event.

-
-

loading…

-
+

kept state

+
+

loading…

+
- -

◆ M1ND H4S QU3STI0NS ◆

-
══════════════════════════════════════════════════════════════
-
-

loading…

-
+

spawn agent

+
+ + +
-

◆ P3NDING APPR0VALS ◆

-
══════════════════════════════════════════════════════════════
-
-

loading…

-
+

update meta inputs

+

checkbox per input; submitting runs nix flake update in /meta/ and rebuilds affected agents (sequentially).

+
+

loading…

+
+
- -

◆ 0PER4T0R 1NB0X ◆

-
══════════════════════════════════════════════════════════════
-
-

loading…

-
+ +
+

◆ 0PER4T0R 1N ◆

-

◆ MESS4GE FL0W ◆

-
══════════════════════════════════════════════════════════════
-

live tail — newest at the top. tap on every send / recv through the broker. compose below: @name picks the recipient (sticky until you @ someone else); tab completes.

-
connecting…
-
- @—> - - +

m1nd has questions

+
+

loading…

+
+ +

pending approvals

+
+

loading…

+
+
+ + +
+

◆ M3SS4G3S ◆

+ +

operator inbox

+
+

loading…

+
+ +

message flow

+

live tail — newest at the top; each row is one broker event. compose below: @name picks the recipient (sticky until you @ someone else); tab completes.

+
connecting…
+
+ @—> + + +
+