mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-06 02:41:48 +00:00
This PR groups the TUI fixes that restore macOS Terminal usability and clean up the theme/composer regressions: - copy transcript selections on macOS drag-release so Terminal.app users can copy while mouse tracking is enabled - copy composer selections on macOS drag-release; composer selection is internal to TextInput and does not use the global Ink selection bus - keep IDE Cmd+C forwarding setup macOS-only, and make keybinding conflict checks respect simple when-clause overlap/negation - force truecolor before chalk initializes (unless NO_COLOR / FORCE_COLOR / HERMES_TUI_TRUECOLOR opt-outs apply) so the default banner keeps its gold/amber/bronze gradient in Terminal.app - move TUI surfaces onto semantic theme tokens and preserve skin prompt symbols as bare tokens with renderer-owned spacing - render focused placeholders as dim hint text in TTY mode instead of inverse/selected-looking synthetic cursor text
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
import { Box, Text } from '@hermes/ink'
|
|
|
|
import { compactPreview } from '../lib/text.js'
|
|
import type { Theme } from '../theme.js'
|
|
|
|
export const QUEUE_WINDOW = 3
|
|
|
|
export function getQueueWindow(queueLen: number, queueEditIdx: number | null) {
|
|
const start =
|
|
queueEditIdx === null ? 0 : Math.max(0, Math.min(queueEditIdx - 1, Math.max(0, queueLen - QUEUE_WINDOW)))
|
|
|
|
const end = Math.min(queueLen, start + QUEUE_WINDOW)
|
|
|
|
return { end, showLead: start > 0, showTail: end < queueLen, start }
|
|
}
|
|
|
|
export function QueuedMessages({ cols, queueEditIdx, queued, t }: QueuedMessagesProps) {
|
|
if (!queued.length) {
|
|
return null
|
|
}
|
|
|
|
const q = getQueueWindow(queued.length, queueEditIdx)
|
|
|
|
return (
|
|
<Box flexDirection="column" marginTop={1}>
|
|
<Text color={t.color.muted} dimColor>
|
|
{`queued (${queued.length})${
|
|
queueEditIdx !== null ? ` · editing ${queueEditIdx + 1} · Ctrl+X delete · Esc cancel` : ''
|
|
}`}
|
|
</Text>
|
|
|
|
{q.showLead && (
|
|
<Text color={t.color.muted} dimColor>
|
|
{' '}
|
|
…
|
|
</Text>
|
|
)}
|
|
|
|
{queued.slice(q.start, q.end).map((item, i) => {
|
|
const idx = q.start + i
|
|
const active = queueEditIdx === idx
|
|
|
|
return (
|
|
<Text color={active ? t.color.accent : t.color.muted} dimColor key={`${idx}-${item.slice(0, 16)}`}>
|
|
{active ? '▸' : ' '} {idx + 1}. {compactPreview(item, Math.max(16, cols - 10))}
|
|
</Text>
|
|
)
|
|
})}
|
|
|
|
{q.showTail && (
|
|
<Text color={t.color.muted} dimColor>
|
|
{' '}…and {queued.length - q.end} more
|
|
</Text>
|
|
)}
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
interface QueuedMessagesProps {
|
|
cols: number
|
|
queueEditIdx: number | null
|
|
queued: string[]
|
|
t: Theme
|
|
}
|