frontend: trim narrated-history comments in packages/agent, packages/swarm-ui
Continues #3901. Same pattern as tabs.js/swarm.js: cut 'used to be X, now Y'/'moved to'/'no longer' change-history narration down to the current design fact, keep every load-bearing rationale intact (the ResizeObserver feedback-loop note in Header.tsx, the Dropdown- vs-real-<a> semantics in MetaNav.tsx, etc.).
This commit is contained in:
parent
56c0602c2f
commit
c2733d2edf
6 changed files with 72 additions and 95 deletions
|
|
@ -10,9 +10,9 @@
|
||||||
resolved as shared CSS rather than a JS component) — see pill.css
|
resolved as shared CSS rather than a JS component) — see pill.css
|
||||||
itself for the classnames it covers. */
|
itself for the classnames it covers. */
|
||||||
@import "@hive/shared/pill.css";
|
@import "@hive/shared/pill.css";
|
||||||
/* Themed dialog/toast component CSS (modal.js) now lives in each
|
/* Themed dialog/toast component CSS (modal.js) lives in each
|
||||||
component's own shadow root (adoptedStyleSheets), not a global
|
component's own shadow root (adoptedStyleSheets), not a global
|
||||||
stylesheet — nothing to @import here any more. */
|
stylesheet — nothing to @import here. */
|
||||||
|
|
||||||
/* ─── full-screen layout overrides ─────────────────────────────────
|
/* ─── full-screen layout overrides ─────────────────────────────────
|
||||||
The agent page mounts a full-viewport terminal under a fixed
|
The agent page mounts a full-viewport terminal under a fixed
|
||||||
|
|
@ -587,9 +587,9 @@ pre.diff {
|
||||||
z-index: 35;
|
z-index: 35;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Composer chrome — used to live inside `.terminal-wrap`; now lives
|
/* Composer chrome lives inside the fixed `.agent-composer` defined
|
||||||
inside the fixed `.agent-composer` defined further up. The base
|
further up. The base rules below stay scoped to whichever ancestor
|
||||||
rules below stay scoped to whichever ancestor owns it. */
|
owns it. */
|
||||||
.term-input .sendform-term {
|
.term-input .sendform-term {
|
||||||
display: flex;
|
display: flex;
|
||||||
/* mara, live: "bottom input row text not aligned / inconsistent
|
/* mara, live: "bottom input row text not aligned / inconsistent
|
||||||
|
|
@ -639,31 +639,29 @@ pre.diff {
|
||||||
.term-input .submit-hint { color: var(--muted); font-size: 0.8em; flex: 0 0 auto; }
|
.term-input .submit-hint { color: var(--muted); font-size: 0.8em; flex: 0 0 auto; }
|
||||||
.term-input.disabled .prompt { color: var(--muted); text-shadow: none; }
|
.term-input.disabled .prompt { color: var(--muted); text-shadow: none; }
|
||||||
.term-input.disabled textarea { color: var(--muted); }
|
.term-input.disabled textarea { color: var(--muted); }
|
||||||
/* Row + pill + details styling moved to hive-fr0nt::TERMINAL_CSS. */
|
|
||||||
|
|
||||||
/* ─── side panel (singleton drawer) ────────────────────────────────
|
/* ─── side panel (singleton drawer) ────────────────────────────────
|
||||||
Inbox + loose-ends details open here instead of expanding inline. The
|
Inbox + loose-ends details open here instead of expanding inline. The
|
||||||
drawer chrome itself (backdrop, drawer, resize handle, header, title,
|
drawer chrome itself (backdrop, drawer, resize handle, header, title,
|
||||||
close button) is now the shared `<hive-side-panel>` element
|
close button) is the shared `<hive-side-panel>` element
|
||||||
(@hive/shared/side-panel.js — this also picks up drag-to-resize,
|
(@hive/shared/side-panel.js, including drag-to-resize); what's left
|
||||||
which this page didn't have before); what's left here is the drag
|
here is the drag cursor-override escape hatch (has to be a global,
|
||||||
cursor-override escape hatch (has to be a global, light-DOM rule — it
|
light-DOM rule — it reaches every element on the page during a
|
||||||
reaches every element on the page during a drag, not just the shared
|
drag, not just the shared element's own shadow tree) and the
|
||||||
element's own shadow tree) and the styling for the panel's own
|
styling for the panel's own content types, which the shared
|
||||||
content types, which the shared element's shadow tree can never
|
element's shadow tree can never reach (see
|
||||||
reach (see @hive/shared/side-panel/hive-side-panel.css's header
|
@hive/shared/side-panel/hive-side-panel.css's header comment). The
|
||||||
comment). The `hive-side-panel .agent-inbox …` rules below use the
|
`hive-side-panel .agent-inbox …` rules below use the element's own
|
||||||
element's own tag name as the selector root — no compatibility class
|
tag name as the selector root — no compatibility class needed, the
|
||||||
needed, the tag name already uniquely identifies the light-DOM
|
tag name already uniquely identifies the light-DOM instance app.js's
|
||||||
instance app.js's `sidePanel` creates. */
|
`sidePanel` creates. */
|
||||||
body.side-panel-resizing {
|
body.side-panel-resizing {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
body.side-panel-resizing * { cursor: ew-resize !important; }
|
body.side-panel-resizing * { cursor: ew-resize !important; }
|
||||||
/* Inbox / loose-ends lists rendered into the side-panel body. The
|
/* Inbox / loose-ends lists rendered into the side-panel body: strip
|
||||||
legacy <details>-collapsible variant of .agent-inbox is gone, so
|
the inbox-only chrome (background, border-left) here and let the
|
||||||
here we strip the inbox-only chrome (background, border-left) and
|
panel body's own padding own the framing. */
|
||||||
let the panel body's own padding own the framing. */
|
|
||||||
hive-side-panel .agent-inbox {
|
hive-side-panel .agent-inbox {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
// <Header> — the agent page's identity strip: icon, glyphic title, the
|
// <Header> — the agent page's identity strip: icon, glyphic title, the
|
||||||
// "swarm / hive" label row, and a slot for the status row
|
// "swarm / hive" label row, and a slot for the status row
|
||||||
// (`<StatusChips>` — ../status-chips/, kept separate so this component
|
// (`<StatusChips>` — ../status-chips/, kept separate so this component
|
||||||
// has no opinion on what badges exist). Same three-column shape as the
|
// has no opinion on what badges exist). Three columns: icon, main
|
||||||
// old `#agent-header` markup (icon · main · pills) — see the `pills`
|
// (title + hive-label), pills — see the `pills` prop doc below for why
|
||||||
// prop doc below for what moved into that third column and why.
|
// the third column is the one that grows. Reuses `agent.css`'s
|
||||||
// Reuses `agent.css`'s existing `.agent-header*`/`.agent-icon` rules
|
// existing `.agent-header*`/`.agent-icon` rules (loaded globally by
|
||||||
// (loaded globally by index.html) rather than a component-scoped
|
// index.html) rather than a component-scoped stylesheet — no new
|
||||||
// stylesheet — no new visual language needed for the chrome itself.
|
// visual language needed for the chrome itself.
|
||||||
|
|
||||||
// Measures its own rendered height via ResizeObserver, writes it to
|
// Measures its own rendered height via ResizeObserver, writes it to
|
||||||
// `--agent-header-real-h` (agent.css's downstream consumers —
|
// `--agent-header-real-h` (agent.css's downstream consumers —
|
||||||
|
|
@ -42,23 +42,18 @@ export interface HeaderProps {
|
||||||
label: string;
|
label: string;
|
||||||
hiveLabel?: string | null;
|
hiveLabel?: string | null;
|
||||||
/** The status/badge row (`<StatusChips>`) — lives in the
|
/** The status/badge row (`<StatusChips>`) — lives in the
|
||||||
* `.agent-header-pills` cluster now, alongside `pills` (see below),
|
* `.agent-header-pills` cluster alongside `pills` (see below), not
|
||||||
* not stacked as its own row under the title. */
|
* stacked as its own row under the title. */
|
||||||
children?: ComponentChildren;
|
children?: ComponentChildren;
|
||||||
/** Flyout triggers (inbox/todos/links pills, the overflow menu
|
/** Flyout triggers (inbox/todos/links pills, the overflow menu
|
||||||
* button) — and, since this round, `children` (the status badges)
|
* button) plus `children` (the status badges), all in
|
||||||
* too, both in `.agent-header-pills`, the SAME header-level column
|
* `.agent-header-pills`. `.agent-header-main` only ever holds the
|
||||||
* the old markup used for pills alone. First pass of this ask
|
* title + hive-label rows, which don't wrap in practice and so stay
|
||||||
* nested pills into a row inside `.agent-header-main` instead —
|
* a stable height; only this pills-cluster column (already sized for
|
||||||
* backwards, mara corrected live: "i meant move badges to where the
|
* a variable pill count) grows to fit badges+pills together, keeping
|
||||||
* dropdowns are, not the other way around. this way the height does
|
* the header a stable height even on widescreen. Meta-nav
|
||||||
* not change even on widescreen" — `.agent-header-main` now only
|
* (`<MetaNav>`) lives here too, as a fixed-size trigger, not an
|
||||||
* ever holds the title + hive-label rows, which don't wrap in
|
* inline link list in the title row (docs/web-ui/agent.md). */
|
||||||
* practice, so it stays a stable height; only this pills-cluster
|
|
||||||
* column (already used to absorbing a variable pill count) grows to
|
|
||||||
* fit badges+pills together. Meta-nav (`<MetaNav>`) lives in here
|
|
||||||
* too, as a fixed-size trigger — not the old markup's inline list in
|
|
||||||
* the title row (`<nav id="meta-links">`, docs/web-ui/agent.md). */
|
|
||||||
pills?: ComponentChildren;
|
pills?: ComponentChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,26 @@
|
||||||
// <MetaNav> — the header's meta-nav trigger: a single fixed-size Badge
|
// <MetaNav> — the header's meta-nav trigger: a single fixed-size Badge
|
||||||
// (`@hive/shared/icons.js`'s `LinkIcon` — an emoji glyph here can't
|
// (`@hive/shared/icons.js`'s `LinkIcon` — an emoji glyph can't match a
|
||||||
// match a neighbouring icon's size/weight on any platform, see that
|
// neighbouring icon's size/weight on any platform, see that file's
|
||||||
// file's comment; mara: "agent page link icons is different from
|
// comment) in the pills cluster that opens a popover listing
|
||||||
// swarm ui" was this trigger still on the old `🔗` emoji after
|
|
||||||
// swarm-ui's own link trigger had already moved to the SVG) in the
|
|
||||||
// pills cluster that opens a popover listing
|
|
||||||
// stats/screen/forge/config + any `hyperhive.dashboardLinks` extras,
|
// stats/screen/forge/config + any `hyperhive.dashboardLinks` extras,
|
||||||
// sourced from the backend's `agent_links()` (the single source of
|
// sourced from the backend's `agent_links()` (the single source of
|
||||||
// truth — same list also feeds the dashboard card's icon strip) — plus
|
// truth — same list also feeds the dashboard card's icon strip) — plus
|
||||||
// a `🧭 dashboard` back-link, formerly the overflow menu's job (mara:
|
// a `🧭 dashboard` back-link.
|
||||||
// "remove rebuild button, move link to dashboards into links menu" —
|
|
||||||
// the overflow `⋯` trigger existed for exactly two items, dashboard-
|
|
||||||
// link and rebuild; rebuild's gone outright, the dashboard's own
|
|
||||||
// R3BU1LD button already covers it, dashboard-link moves here, so
|
|
||||||
// `OverflowMenu` had nothing left to justify existing and is deleted).
|
|
||||||
//
|
//
|
||||||
// `variant="quiet"` — mara: "link and settings button should not have
|
// `variant="quiet"` — mara: "link and settings button should not have
|
||||||
// the badge bg". `Badge`'s default filled-pill look is right for a
|
// the badge bg". `Badge`'s default filled-pill look is right for a
|
||||||
// status/picker chip, wrong for this icon-only trigger, which should
|
// status/picker chip, wrong for this icon-only trigger, which should
|
||||||
// read as header chrome. See `@hive/shared/badge.js`'s `BadgeVariant`.
|
// read as header chrome. See `@hive/shared/badge.js`'s `BadgeVariant`.
|
||||||
|
//
|
||||||
// v1 of this rendered every link inline in the header's title row —
|
// A popover keeps the header height fixed — a variable-width inline
|
||||||
// mara, live: "the login card looks like it is behind the header"
|
// link list would grow the title row past the fixed `--agent-header-h`
|
||||||
// (a variable-width link list can grow the title row past the fixed
|
// the rest of the page is offset against (see Header.tsx's comment).
|
||||||
// `--agent-header-h` the rest of the page is offset against — see
|
// Real `<a>` items, not `@hive/shared`'s `Dropdown` (its items are
|
||||||
// Header.tsx's comment) and "the links should have the same popout as
|
// always `<button>`s for command dispatch, which would lose real link
|
||||||
// the links in the nav bar of swarm-ui." This is that: one quiet icon
|
// semantics like ctrl/middle-click and "copy link address"), but
|
||||||
// trigger (reuses `@hive/shared`'s `Badge`, icon-only), a popover on
|
// matching its `.ui-dropdown` visual values exactly (see MetaNav.css) —
|
||||||
// click, real `<a>` items — not `@hive/shared`'s `Dropdown` (its items
|
// the same "reuse the values, not the component" call `LoginFlow`'s
|
||||||
// are always `<button>`s for command dispatch, which would lose real
|
// `.login-card` makes for the same reason.
|
||||||
// link semantics like ctrl/middle-click and "copy link address") —
|
|
||||||
// but matching its `.ui-dropdown` visual values exactly (see
|
|
||||||
// MetaNav.css), the same "reuse the values, not the component" call
|
|
||||||
// `LoginFlow`'s `.login-card` already made for the same reason.
|
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import { Badge } from '@hive/shared/badge.js';
|
import { Badge } from '@hive/shared/badge.js';
|
||||||
import { LinkIcon } from '@hive/shared/icons.js';
|
import { LinkIcon } from '@hive/shared/icons.js';
|
||||||
|
|
@ -73,8 +61,8 @@ export function MetaNav({ links, forgePublicUrl, dashboardBase }: MetaNavProps)
|
||||||
// entirely (never guessed from `<host>:3000`); `external` is already
|
// entirely (never guessed from `<host>:3000`); `external` is already
|
||||||
// absolute; `container` is a same-origin path.
|
// absolute; `container` is a same-origin path.
|
||||||
const visible = links.filter((lnk) => lnk.kind !== 'forge' || forgePublicUrl);
|
const visible = links.filter((lnk) => lnk.kind !== 'forge' || forgePublicUrl);
|
||||||
// No early-return-on-empty any more — the dashboard link below is
|
// No early-return-on-empty: the dashboard link below is always
|
||||||
// always present, so the trigger always has at least one item.
|
// present, so the trigger always has at least one item.
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="meta-nav-anchor" ref={rootRef}>
|
<div class="meta-nav-anchor" ref={rootRef}>
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,11 @@
|
||||||
// calls — exactly why the bulk endpoint exists instead of looping the
|
// calls — exactly why the bulk endpoint exists instead of looping the
|
||||||
// single-agent one.
|
// single-agent one.
|
||||||
//
|
//
|
||||||
// Owns the "+ agent" trigger too: creation used to be its own
|
// Owns the "+ agent" trigger too — the roster this populates is the
|
||||||
// `/create-agent` route + nav item, but the roster this populates is
|
// natural home for the action that populates it; a separate top-level
|
||||||
// the natural home for the action that populates it — a separate top-
|
// nav entry would be one click of indirection for no benefit. The form
|
||||||
// level nav entry was one click of indirection for no benefit. The form
|
// itself (`CreateAgentForm`) mounts inside a `Dialog` here rather than
|
||||||
// itself (`CreateAgentForm`) is unchanged from its page days, just
|
// its own route.
|
||||||
// mounted inside a `Dialog` instead of a route.
|
|
||||||
import { useState } from 'preact/hooks';
|
import { useState } from 'preact/hooks';
|
||||||
import { ApiErrorPanel } from '@hive/shared/api-error-panel.js';
|
import { ApiErrorPanel } from '@hive/shared/api-error-panel.js';
|
||||||
import { readApiError, type ProblemDetails } from '@hive/shared/api-error.js';
|
import { readApiError, type ProblemDetails } from '@hive/shared/api-error.js';
|
||||||
|
|
|
||||||
|
|
@ -179,10 +179,7 @@ export function CreateAgentForm() {
|
||||||
literal behaviour (deploying the container onto the hive isn't
|
literal behaviour (deploying the container onto the hive isn't
|
||||||
wired up server-side yet — see this file's top comment) —
|
wired up server-side yet — see this file's top comment) —
|
||||||
mara's explicit call on this copy: read as finished, not as a
|
mara's explicit call on this copy: read as finished, not as a
|
||||||
running commentary on partial implementation. The 🪪 glyph that
|
running commentary on partial implementation. */}
|
||||||
used to sit here as body copy now lives on `Panel`'s own `icon`
|
|
||||||
prop instead — it's what prompted that prop to exist at all
|
|
||||||
(see Panel.tsx's doc comment) */}
|
|
||||||
<Panel title="what this creates" icon="🪪">
|
<Panel title="what this creates" icon="🪪">
|
||||||
<p>
|
<p>
|
||||||
Submitting this queues everything a new agent needs: a swarm-level identity, a config
|
Submitting this queues everything a new agent needs: a swarm-level identity, a config
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,16 @@
|
||||||
// Page-switch animation, two pieces (motion-guard rules live in
|
// Page-switch animation, two pieces (motion-guard rules live in
|
||||||
// Shell.css): `.shell-body` remounts on every navigation
|
// Shell.css): `.shell-body` remounts on every navigation
|
||||||
// (`key={location}`) to replay a plain fade-in, and a single shared
|
// (`key={location}`) to replay a plain fade-in, and a single shared
|
||||||
// underline (`.shell-nav-indicator`, replacing what used to be a
|
// underline (`.shell-nav-indicator`) hops through every nav item it
|
||||||
// per-link border) hops through every nav item it passes over on its
|
// passes over on its way to the new active one, not just a straight
|
||||||
// way to the new active one, not just a straight two-point tween — a
|
// two-point tween — a nav hives→components jump visibly touches "new
|
||||||
// nav hives→components jump visibly touches "new agent" and "jobs" in
|
// agent" and "jobs" in between, position and colour together. Accent
|
||||||
// between, position and colour together. Accent is a discrete cycle
|
// is a discrete cycle through the existing base16 chromatic slots
|
||||||
// through the existing base16 chromatic slots (`NAV_ITEMS`' `accent`
|
// (`NAV_ITEMS`' `accent` field), not a continuous hue rotation —
|
||||||
// field), not a continuous hue rotation — everything here still
|
// everything here still derives from base16, same rule the rest of
|
||||||
// derives from base16, same rule the rest of the palette follows.
|
// the palette follows. `.shell-brand` rides the identical accent value
|
||||||
// `.shell-brand` rides the identical accent value (`navAccent` below),
|
// (`navAccent` below), so the header reads as one accent changing, not
|
||||||
// so the header reads as one accent changing, not the underline alone.
|
// the underline alone.
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import type { ComponentChildren } from 'preact';
|
import type { ComponentChildren } from 'preact';
|
||||||
import { Link, useLocation } from 'wouter-preact';
|
import { Link, useLocation } from 'wouter-preact';
|
||||||
|
|
@ -109,10 +109,10 @@ function NavLink({
|
||||||
return (
|
return (
|
||||||
<Link href={href} className="shell-nav-link">
|
<Link href={href} className="shell-nav-link">
|
||||||
{/* Touch target (min-height) lives on the <a> so the whole row is
|
{/* Touch target (min-height) lives on the <a> so the whole row is
|
||||||
tappable. The underline itself no longer lives here — see
|
tappable. The underline lives on the shared
|
||||||
`.shell-nav-indicator` — this span is still what gets
|
`.shell-nav-indicator`, not here — this span is still what
|
||||||
measured to position that shared indicator, so it hugs just
|
gets measured to position it, so it hugs just the text rather
|
||||||
the text rather than the full-height tappable box. */}
|
than the full-height tappable box. */}
|
||||||
<span
|
<span
|
||||||
ref={textRef}
|
ref={textRef}
|
||||||
class={'shell-nav-link-text' + (active ? ' shell-nav-link-active' : '')}
|
class={'shell-nav-link-text' + (active ? ' shell-nav-link-active' : '')}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue