mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-02 02:01:47 +00:00
style(tui): apply npm run fix
Run the TUI lint autofix and formatter on the PR branch after the sticky prompt and paste recovery changes.
This commit is contained in:
parent
d7ae8dfd0a
commit
f542d17b00
20 changed files with 60 additions and 52 deletions
|
|
@ -714,9 +714,7 @@ describe('createGatewayEventHandler', () => {
|
|||
} as any)
|
||||
|
||||
// Pre-interrupt todos should land in turn state.
|
||||
expect(getTurnState().todos).toEqual([
|
||||
{ content: 'pre-interrupt', id: 'todo-1', status: 'pending' }
|
||||
])
|
||||
expect(getTurnState().todos).toEqual([{ content: 'pre-interrupt', id: 'todo-1', status: 'pending' }])
|
||||
|
||||
turnController.interruptTurn({
|
||||
appendMessage: (msg: Msg) => appended.push(msg),
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
// it overlaps any context, including our terminal scope. We must NOT
|
||||
// silently add a terminal-scoped cmd+c that would shadow it.
|
||||
const mkdir = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
const readFile = vi.fn().mockResolvedValue(
|
||||
JSON.stringify([
|
||||
{
|
||||
|
|
@ -149,6 +150,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
}
|
||||
])
|
||||
)
|
||||
|
||||
const writeFile = vi.fn().mockResolvedValue(undefined)
|
||||
const copyFile = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
|
|
@ -170,6 +172,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
// would shadow ours. Treat as a conflict even though the strings
|
||||
// aren't identical.
|
||||
const mkdir = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
const readFile = vi.fn().mockResolvedValue(
|
||||
JSON.stringify([
|
||||
{
|
||||
|
|
@ -179,6 +182,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
}
|
||||
])
|
||||
)
|
||||
|
||||
const writeFile = vi.fn().mockResolvedValue(undefined)
|
||||
const copyFile = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
|
|
@ -198,6 +202,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
// logically disjoint from our copy-forwarding binding, which requires
|
||||
// terminalTextSelected.
|
||||
const mkdir = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
const readFile = vi.fn().mockResolvedValue(
|
||||
JSON.stringify([
|
||||
{
|
||||
|
|
@ -208,6 +213,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
}
|
||||
])
|
||||
)
|
||||
|
||||
const writeFile = vi.fn().mockResolvedValue(undefined)
|
||||
const copyFile = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
|
|
@ -226,6 +232,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
// clauses don't overlap. A user's pre-existing cmd+c binding scoped to
|
||||
// editor focus should NOT block our terminal-scoped cmd+c binding.
|
||||
const mkdir = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
const readFile = vi.fn().mockResolvedValue(
|
||||
JSON.stringify([
|
||||
{
|
||||
|
|
@ -235,6 +242,7 @@ describe('configureTerminalKeybindings', () => {
|
|||
}
|
||||
])
|
||||
)
|
||||
|
||||
const writeFile = vi.fn().mockResolvedValue(undefined)
|
||||
const copyFile = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,14 +16,16 @@ const RELEVANT_ENV = [
|
|||
'HERMES_TUI_THEME',
|
||||
'HERMES_TUI_BACKGROUND',
|
||||
'COLORFGBG',
|
||||
'TERM_PROGRAM',
|
||||
'TERM_PROGRAM'
|
||||
] as const
|
||||
|
||||
async function importThemeWithCleanEnv() {
|
||||
for (const key of RELEVANT_ENV) {
|
||||
vi.stubEnv(key, '')
|
||||
}
|
||||
|
||||
vi.resetModules()
|
||||
|
||||
return import('../theme.js')
|
||||
}
|
||||
|
||||
|
|
@ -165,9 +167,7 @@ describe('detectLightMode', () => {
|
|||
expect(detectLightMode({ TERM_PROGRAM: 'Apple_Terminal' }, allowList)).toBe(true)
|
||||
|
||||
// Dark COLORFGBG must beat the allow-list.
|
||||
expect(
|
||||
detectLightMode({ COLORFGBG: '15;0', TERM_PROGRAM: 'Apple_Terminal' }, allowList),
|
||||
).toBe(false)
|
||||
expect(detectLightMode({ COLORFGBG: '15;0', TERM_PROGRAM: 'Apple_Terminal' }, allowList)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -373,6 +373,7 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
// 120-char clip used for `gateway.stderr` activity entries.
|
||||
const STDERR_LINE_CAP = 120
|
||||
const STDERR_LINES_MAX = 8
|
||||
|
||||
const tailLines = (stderrTail ?? '')
|
||||
.split('\n')
|
||||
.map(l => l.trim())
|
||||
|
|
|
|||
|
|
@ -290,21 +290,19 @@ export const sessionCommands: SlashCommand[] = [
|
|||
return ctx.transcript.sys(`usage: /indicator [${INDICATOR_STYLES.join('|')}]`)
|
||||
}
|
||||
|
||||
ctx.gateway
|
||||
.rpc<ConfigSetResponse>('config.set', { key: 'indicator', value })
|
||||
.then(
|
||||
ctx.guarded<ConfigSetResponse>(r => {
|
||||
if (!r.value) {
|
||||
return
|
||||
}
|
||||
ctx.gateway.rpc<ConfigSetResponse>('config.set', { key: 'indicator', value }).then(
|
||||
ctx.guarded<ConfigSetResponse>(r => {
|
||||
if (!r.value) {
|
||||
return
|
||||
}
|
||||
|
||||
// Hot-swap the running TUI immediately so the next render
|
||||
// uses the new style without waiting for the 5s mtime poll
|
||||
// to re-apply config.full.
|
||||
patchUiState({ indicatorStyle: value as IndicatorStyle })
|
||||
ctx.transcript.sys(`indicator → ${r.value}`)
|
||||
})
|
||||
)
|
||||
// Hot-swap the running TUI immediately so the next render
|
||||
// uses the new style without waiting for the 5s mtime poll
|
||||
// to re-apply config.full.
|
||||
patchUiState({ indicatorStyle: value as IndicatorStyle })
|
||||
ctx.transcript.sys(`indicator → ${r.value}`)
|
||||
})
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import type {
|
|||
import { asRpcResult } from '../lib/rpc.js'
|
||||
|
||||
import {
|
||||
type BusyInputMode,
|
||||
DEFAULT_INDICATOR_STYLE,
|
||||
INDICATOR_STYLES,
|
||||
type BusyInputMode,
|
||||
type IndicatorStyle,
|
||||
type StatusBarMode,
|
||||
type StatusBarMode
|
||||
} from './interfaces.js'
|
||||
import { turnController } from './turnController.js'
|
||||
import { patchUiState } from './uiStore.js'
|
||||
|
|
|
|||
|
|
@ -366,6 +366,7 @@ export function useInputHandlers(ctx: InputHandlerContext): InputHandlerResult {
|
|||
|
||||
if (isCtrl(key, ch, 'x') && cState.queueEditIdx !== null) {
|
||||
cActions.removeQueue(cState.queueEditIdx)
|
||||
|
||||
return cActions.clearIn()
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +394,7 @@ export function useInputHandlers(ctx: InputHandlerContext): InputHandlerResult {
|
|||
if (isAction(key, ch, 'l')) {
|
||||
clearSelection()
|
||||
forceRedraw(terminal.stdout ?? process.stdout)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ export function useSubmission(opts: UseSubmissionOptions) {
|
|||
(full: string, opts: { fallbackToFront?: boolean } = {}) => {
|
||||
const live = getUiState()
|
||||
const mode = live.busyInputMode
|
||||
|
||||
const fallback = (note: string) => {
|
||||
if (opts.fallbackToFront) {
|
||||
composerRefs.queueRef.current.unshift(full)
|
||||
|
|
@ -234,6 +235,7 @@ export function useSubmission(opts: UseSubmissionOptions) {
|
|||
} else {
|
||||
composerActions.enqueue(full)
|
||||
}
|
||||
|
||||
sys(note)
|
||||
}
|
||||
|
||||
|
|
@ -350,17 +352,7 @@ export function useSubmission(opts: UseSubmissionOptions) {
|
|||
|
||||
send(full)
|
||||
},
|
||||
[
|
||||
appendMessage,
|
||||
composerActions,
|
||||
composerRefs,
|
||||
handleBusyInput,
|
||||
interpolate,
|
||||
send,
|
||||
sendQueued,
|
||||
shellExec,
|
||||
slashRef
|
||||
]
|
||||
[appendMessage, composerActions, composerRefs, handleBusyInput, interpolate, send, sendQueued, shellExec, slashRef]
|
||||
)
|
||||
|
||||
const submit = useCallback(
|
||||
|
|
|
|||
|
|
@ -671,9 +671,7 @@ function DiffView({
|
|||
<Text color={t.color.text}>
|
||||
{diffMetricLine('duration', aTotals.totalDuration, bTotals.totalDuration, n => `${n.toFixed(1)}s`)}
|
||||
</Text>
|
||||
<Text color={t.color.text}>
|
||||
{diffMetricLine('tokens', sumTokens(aTotals), sumTokens(bTotals), fmtTokens)}
|
||||
</Text>
|
||||
<Text color={t.color.text}>{diffMetricLine('tokens', sumTokens(aTotals), sumTokens(bTotals), fmtTokens)}</Text>
|
||||
<Text color={t.color.text}>{diffMetricLine('cost', aTotals.costUsd, bTotals.costUsd, dollars)}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import unicodeSpinners from 'unicode-animations'
|
|||
|
||||
import { $delegationState } from '../app/delegationStore.js'
|
||||
import type { IndicatorStyle } from '../app/interfaces.js'
|
||||
import { $uiState } from '../app/uiStore.js'
|
||||
import { useTurnSelector } from '../app/turnStore.js'
|
||||
import { $uiState } from '../app/uiStore.js'
|
||||
import { FACES } from '../content/faces.js'
|
||||
import { VERBS } from '../content/verbs.js'
|
||||
import { fmtDuration } from '../domain/messages.js'
|
||||
|
|
|
|||
|
|
@ -224,7 +224,12 @@ const ComposerPane = memo(function ComposerPane({
|
|||
</Box>
|
||||
))}
|
||||
|
||||
<Box onMouseDown={captureInputDrag} onMouseDrag={dragFromPromptRow} onMouseUp={endInputDrag} position="relative">
|
||||
<Box
|
||||
onMouseDown={captureInputDrag}
|
||||
onMouseDrag={dragFromPromptRow}
|
||||
onMouseUp={endInputDrag}
|
||||
position="relative"
|
||||
>
|
||||
<Box width={promptWidth}>
|
||||
{sh ? (
|
||||
<Text color={ui.theme.color.shellDollar}>{promptLabel}</Text>
|
||||
|
|
|
|||
|
|
@ -133,7 +133,12 @@ export function SessionPicker({ gw, onCancel, onSelect, t }: SessionPickerProps)
|
|||
</Text>
|
||||
</Box>
|
||||
|
||||
<Text bold={selected} color={selected ? t.color.accent : t.color.muted} inverse={selected} wrap="truncate-end">
|
||||
<Text
|
||||
bold={selected}
|
||||
color={selected ? t.color.accent : t.color.muted}
|
||||
inverse={selected}
|
||||
wrap="truncate-end"
|
||||
>
|
||||
{s.title || s.preview || '(untitled)'}
|
||||
</Text>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Box, NoSelect, Text } from '@hermes/ink'
|
||||
import { memo, useEffect, useMemo, useState, type ReactNode } from 'react'
|
||||
import { memo, type ReactNode, useEffect, useMemo, useState } from 'react'
|
||||
import spinners, { type BrailleSpinnerName } from 'unicode-animations'
|
||||
|
||||
import { THINKING_COT_MAX } from '../config/limits.js'
|
||||
|
|
|
|||
|
|
@ -21,14 +21,11 @@
|
|||
* no effect.
|
||||
*/
|
||||
|
||||
if (
|
||||
process.env.HERMES_TUI_TRUECOLOR !== '0' &&
|
||||
!process.env.NO_COLOR &&
|
||||
!process.env.FORCE_COLOR
|
||||
) {
|
||||
if (process.env.HERMES_TUI_TRUECOLOR !== '0' && !process.env.NO_COLOR && !process.env.FORCE_COLOR) {
|
||||
if (!process.env.COLORTERM) {
|
||||
process.env.COLORTERM = 'truecolor'
|
||||
}
|
||||
|
||||
process.env.FORCE_COLOR = '3'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ export async function configureTerminalKeybindings(
|
|||
}
|
||||
|
||||
const targets = targetBindings(platform)
|
||||
|
||||
const conflicts = targets.filter(target =>
|
||||
keybindings.some(existing => isKeybinding(existing) && bindingsConflict(existing, target))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ function backgroundLuminance(raw: string): null | number {
|
|||
}
|
||||
|
||||
const hex = v.startsWith('#') ? v.slice(1) : v
|
||||
|
||||
const rgb = HEX_6_RE.test(hex)
|
||||
? [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16)]
|
||||
: HEX_3_RE.test(hex)
|
||||
|
|
@ -254,7 +255,7 @@ export function detectLightMode(
|
|||
env: NodeJS.ProcessEnv = process.env,
|
||||
// Injectable so tests can prove the COLORFGBG-over-TERM_PROGRAM
|
||||
// precedence rule even though the production allow-list is empty.
|
||||
lightDefaultTermPrograms: ReadonlySet<string> = LIGHT_DEFAULT_TERM_PROGRAMS,
|
||||
lightDefaultTermPrograms: ReadonlySet<string> = LIGHT_DEFAULT_TERM_PROGRAMS
|
||||
): boolean {
|
||||
const lightFlag = (env.HERMES_TUI_LIGHT ?? '').trim().toLowerCase()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue