hermes-agent/ui-tui/src/app/overlayStore.ts
Brooklyn Nicholson e971dc1e9d feat(journey): CLI + TUI learning timeline (/journey)
Terminal rendition of the desktop Star Map / Memory Graph: learned skills
and memories on a timeline, shared by `hermes journey` and the TUI
`/journey` overlay via one size-aware Python renderer
(agent/learning_graph_render.py).

- TUI overlay mirrors /agents: static chart overview + selectable slice
  list → slice detail → single skill/memory body, with the shared
  inverse-row selection treatment and a pinned footer.
- Reuse primitives: extract OverlayScrollbar into its own module (now
  shared with agentsOverlay), scroll the item body via ScrollBox, and
  unify both lists through one table-driven ListRow.
- No animation/playback in the TUI — pure data; the renderer's reveal
  scrubber stays available in the CLI (`--play`, `--reveal`).
2026-06-30 04:44:58 -05:00

88 lines
2.3 KiB
TypeScript

import { atom, computed } from 'nanostores'
import type { OverlayState } from './interfaces.js'
const buildOverlayState = (): OverlayState => ({
agents: false,
agentsInitialHistoryIndex: 0,
approval: null,
billing: null,
clarify: null,
confirm: null,
journey: false,
modelPicker: false,
pager: null,
petPicker: false,
pluginsHub: false,
secret: null,
sessions: false,
skillsHub: false,
sudo: null
})
export const $overlayState = atom<OverlayState>(buildOverlayState())
export const $isBlocked = computed(
$overlayState,
({
agents,
approval,
billing,
clarify,
confirm,
journey,
modelPicker,
pager,
petPicker,
pluginsHub,
secret,
sessions,
skillsHub,
sudo
}) =>
Boolean(
agents ||
approval ||
billing ||
clarify ||
confirm ||
journey ||
modelPicker ||
pager ||
petPicker ||
pluginsHub ||
secret ||
sessions ||
skillsHub ||
sudo
)
)
export const getOverlayState = () => $overlayState.get()
export const patchOverlayState = (next: Partial<OverlayState> | ((state: OverlayState) => OverlayState)) =>
$overlayState.set(typeof next === 'function' ? next($overlayState.get()) : { ...$overlayState.get(), ...next })
/** Full reset — used by session/turn teardown and tests. */
export const resetOverlayState = () => $overlayState.set(buildOverlayState())
/**
* Soft reset: drop FLOW-scoped overlays (approval / clarify / confirm / sudo
* / secret / pager) but PRESERVE user-toggled ones — agents dashboard, model
* picker, skills hub, sessions overlay. Those are opened deliberately and
* shouldn't vanish when a turn ends. Called from turnController.idle() on
* every turn completion / interrupt; the old "reset everything" behaviour
* silently closed /agents the moment delegation finished.
*/
export const resetFlowOverlays = () =>
$overlayState.set({
...buildOverlayState(),
agents: $overlayState.get().agents,
agentsInitialHistoryIndex: $overlayState.get().agentsInitialHistoryIndex,
journey: $overlayState.get().journey,
modelPicker: $overlayState.get().modelPicker,
petPicker: $overlayState.get().petPicker,
pluginsHub: $overlayState.get().pluginsHub,
sessions: $overlayState.get().sessions,
skillsHub: $overlayState.get().skillsHub
})