Home screen now shows the canonical HERMES-AGENT block logo (hermes_cli/banner.py, gold->amber->bronze via primary/accent/border tokens; width-guarded to a compact brand line under 102 cols) plus a collapsible '▶ N tools · M skills · K MCP' panel that expands to per-toolset / per-category / per-server detail. Data comes from a new opt-in gateway RPC 'startup.catalog' (aggregates get_all_toolsets + banner.get_available_skills + config mcp_servers); the native engine fetches it best-effort on session start (Effect.catchCause swallows it on old gateways). Opt-in => Ink path untouched. py_compile OK. Store gains a typed Catalog + defensive setCatalog mapper. +2 tests (90 pass); verified live (1185 tools / 196 skills / 2 MCP, expand shows the full lists).
33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
/**
|
|
* Transcript — the scrolling message pane (spec v4 §2 `view/transcript.tsx`).
|
|
*
|
|
* ONE full-height <scrollbox> with a reactive <For> (opencode's model — the
|
|
* viewport clips growing output so terminal scrollback is never corrupted; no
|
|
* `writeToScrollback`). Carries the §8 #2 gotchas EXACTLY:
|
|
* - `minHeight:0` on BOTH the wrapper box AND the <scrollbox> (so the flex
|
|
* child can shrink below content height instead of pushing the composer off),
|
|
* - NO `flexDirection` on the <scrollbox> ROOT style (it has internal
|
|
* viewport/content children; setting it there breaks content-height
|
|
* measurement → phantom scroll offset that clips the top + leaves a gap),
|
|
* - `stickyScroll` + `stickyStart="bottom"` to pin the latest line.
|
|
*/
|
|
import { For, Show } from 'solid-js'
|
|
|
|
import type { SessionStore } from '../logic/store.ts'
|
|
import { HomeHint } from './homeHint.tsx'
|
|
import { MessageLine } from './messageLine.tsx'
|
|
|
|
export function Transcript(props: { store: SessionStore }) {
|
|
return (
|
|
<box style={{ flexGrow: 1, minHeight: 0, marginTop: 1 }}>
|
|
<scrollbox style={{ flexGrow: 1, minHeight: 0 }} stickyScroll stickyStart="bottom">
|
|
{/* empty-transcript home screen (item 12); replaced by messages on the first turn */}
|
|
<Show when={props.store.state.messages.length === 0}>
|
|
<HomeHint catalog={props.store.state.catalog} />
|
|
</Show>
|
|
<For each={props.store.state.messages}>{message => <MessageLine message={message} />}</For>
|
|
</scrollbox>
|
|
</box>
|
|
)
|
|
}
|