refactor(tui): /clean pass on tui-polish — data tables, tighter title
- normalizeStatusBar: replace Set + early-returns + cast with a single
alias lookup table. Handles legacy `false`, trims/lowercases strings,
maps `on` → `top` in one pass. One expression, no `as` hacks.
- Tab title block: drop the narrative comment, fold
blockedOnInput/titleStatus/cwdTag/terminalTitle into inline expressions
inside useTerminalTitle. Avoids shadowing the outer `cwd`.
- tui_gateway statusbar set branch: read `display` once instead of
`cfg0.get("display")` twice.
This commit is contained in:
@@ -2528,8 +2528,8 @@ def _(rid, params: dict) -> dict:
|
|||||||
|
|
||||||
if key == "statusbar":
|
if key == "statusbar":
|
||||||
raw = str(value or "").strip().lower()
|
raw = str(value or "").strip().lower()
|
||||||
cfg0 = _load_cfg()
|
display = _load_cfg().get("display")
|
||||||
d0 = cfg0.get("display") if isinstance(cfg0.get("display"), dict) else {}
|
d0 = display if isinstance(display, dict) else {}
|
||||||
current = _coerce_statusbar(d0.get("tui_statusbar", "top"))
|
current = _coerce_statusbar(d0.get("tui_statusbar", "top"))
|
||||||
|
|
||||||
if raw in ("", "toggle"):
|
if raw in ("", "toggle"):
|
||||||
|
|||||||
@@ -14,23 +14,16 @@ import type { StatusBarMode } from './interfaces.js'
|
|||||||
import { turnController } from './turnController.js'
|
import { turnController } from './turnController.js'
|
||||||
import { patchUiState } from './uiStore.js'
|
import { patchUiState } from './uiStore.js'
|
||||||
|
|
||||||
const STATUSBAR_MODES = new Set<StatusBarMode>(['bottom', 'off', 'top'])
|
const STATUSBAR_ALIAS: Record<string, StatusBarMode> = {
|
||||||
|
bottom: 'bottom',
|
||||||
export const normalizeStatusBar = (raw: unknown): StatusBarMode => {
|
off: 'off',
|
||||||
if (raw === false) {
|
on: 'top',
|
||||||
return 'off'
|
top: 'top'
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof raw !== 'string') {
|
|
||||||
return 'top'
|
|
||||||
}
|
|
||||||
|
|
||||||
const v = raw.trim().toLowerCase()
|
|
||||||
const mode = (v === 'on' ? 'top' : v) as StatusBarMode
|
|
||||||
|
|
||||||
return STATUSBAR_MODES.has(mode) ? mode : 'top'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const normalizeStatusBar = (raw: unknown): StatusBarMode =>
|
||||||
|
raw === false ? 'off' : typeof raw === 'string' ? STATUSBAR_ALIAS[raw.trim().toLowerCase()] ?? 'top' : 'top'
|
||||||
|
|
||||||
const MTIME_POLL_MS = 5000
|
const MTIME_POLL_MS = 5000
|
||||||
|
|
||||||
const quietRpc = async <T extends Record<string, any> = Record<string, any>>(
|
const quietRpc = async <T extends Record<string, any> = Record<string, any>>(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type ScrollBoxHandle, useApp, useHasSelection, useSelection, useStdout, useTerminalTitle } from '@hermes/ink'
|
import { useApp, useHasSelection, useSelection, useStdout, useTerminalTitle, type ScrollBoxHandle } from '@hermes/ink'
|
||||||
import { useStore } from '@nanostores/react'
|
import { useStore } from '@nanostores/react'
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
|
||||||
@@ -314,16 +314,15 @@ export function useMainApp(gw: GatewayClient) {
|
|||||||
|
|
||||||
useConfigSync({ gw, setBellOnComplete, setVoiceEnabled, sid: ui.sid })
|
useConfigSync({ gw, setBellOnComplete, setVoiceEnabled, sid: ui.sid })
|
||||||
|
|
||||||
// ── Terminal tab title ─────────────────────────────────────────────
|
// Tab title: `⚠` waiting on approval/sudo/secret/clarify, `⏳` busy, `✓` idle.
|
||||||
// model + cwd + 3-state marker so multi-instance users can spot which tab
|
const model = ui.info?.model?.replace(/^.*\//, '') ?? ''
|
||||||
// is working, which is idle, and which is waiting on them.
|
const marker =
|
||||||
// `⚠` blocked on approval/sudo/secret/clarify, `⏳` busy, `✓` idle.
|
overlay.approval || overlay.sudo || overlay.secret || overlay.clarify ? '⚠' : ui.busy ? '⏳' : '✓'
|
||||||
const shortModel = ui.info?.model?.replace(/^.*\//, '') ?? ''
|
const tabCwd = ui.info?.cwd
|
||||||
const blockedOnInput = !!(overlay.approval || overlay.sudo || overlay.secret || overlay.clarify)
|
|
||||||
const titleStatus = blockedOnInput ? '⚠' : ui.busy ? '⏳' : '✓'
|
useTerminalTitle(
|
||||||
const cwdTag = ui.info?.cwd ? ` · ${shortCwd(ui.info.cwd, 24)}` : ''
|
model ? `${marker} ${model}${tabCwd ? ` · ${shortCwd(tabCwd, 24)}` : ''}` : 'Hermes'
|
||||||
const terminalTitle = shortModel ? `${titleStatus} ${shortModel}${cwdTag}` : 'Hermes'
|
)
|
||||||
useTerminalTitle(terminalTitle)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ui.sid || !stdout) {
|
if (!ui.sid || !stdout) {
|
||||||
|
|||||||
Reference in New Issue
Block a user