mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-07 02:51:50 +00:00
fix(tui): wire Ctrl+L to Ink forceRedraw path
Expose a small forceRedraw API from @hermes/ink and use it for Ctrl/Cmd+L so the hotkey performs a real terminal clear + full repaint instead of a no-op state patch.
This commit is contained in:
parent
da6f8449a5
commit
b3e7a412e2
4 changed files with 16 additions and 6 deletions
2
ui-tui/packages/hermes-ink/index.d.ts
vendored
2
ui-tui/packages/hermes-ink/index.d.ts
vendored
|
|
@ -30,7 +30,7 @@ export { useTerminalFocus } from './src/ink/hooks/use-terminal-focus.ts'
|
||||||
export { useTerminalTitle } from './src/ink/hooks/use-terminal-title.ts'
|
export { useTerminalTitle } from './src/ink/hooks/use-terminal-title.ts'
|
||||||
export { useTerminalViewport } from './src/ink/hooks/use-terminal-viewport.ts'
|
export { useTerminalViewport } from './src/ink/hooks/use-terminal-viewport.ts'
|
||||||
export { default as measureElement } from './src/ink/measure-element.ts'
|
export { default as measureElement } from './src/ink/measure-element.ts'
|
||||||
export { createRoot, default as render, renderSync } from './src/ink/root.ts'
|
export { createRoot, default as render, forceRedraw, renderSync } from './src/ink/root.ts'
|
||||||
export type { Instance, RenderOptions, Root } from './src/ink/root.ts'
|
export type { Instance, RenderOptions, Root } from './src/ink/root.ts'
|
||||||
export { stringWidth } from './src/ink/stringWidth.ts'
|
export { stringWidth } from './src/ink/stringWidth.ts'
|
||||||
export { default as TextInput, UncontrolledTextInput } from 'ink-text-input'
|
export { default as TextInput, UncontrolledTextInput } from 'ink-text-input'
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export { useTerminalTitle } from './ink/hooks/use-terminal-title.js'
|
||||||
export { useTerminalViewport } from './ink/hooks/use-terminal-viewport.js'
|
export { useTerminalViewport } from './ink/hooks/use-terminal-viewport.js'
|
||||||
export { default as measureElement } from './ink/measure-element.js'
|
export { default as measureElement } from './ink/measure-element.js'
|
||||||
export { scrollFastPathStats, type ScrollFastPathStats } from './ink/render-node-to-output.js'
|
export { scrollFastPathStats, type ScrollFastPathStats } from './ink/render-node-to-output.js'
|
||||||
export { createRoot, default as render, renderSync } from './ink/root.js'
|
export { createRoot, default as render, forceRedraw, renderSync } from './ink/root.js'
|
||||||
export { stringWidth } from './ink/stringWidth.js'
|
export { stringWidth } from './ink/stringWidth.js'
|
||||||
export { isXtermJs } from './ink/terminal.js'
|
export { isXtermJs } from './ink/terminal.js'
|
||||||
export { default as TextInput, UncontrolledTextInput } from 'ink-text-input'
|
export { default as TextInput, UncontrolledTextInput } from 'ink-text-input'
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,16 @@ export type Root = {
|
||||||
waitUntilExit: () => Promise<void>
|
waitUntilExit: () => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const forceRedraw = (stdout: NodeJS.WriteStream = process.stdout): boolean => {
|
||||||
|
const instance = instances.get(stdout)
|
||||||
|
if (!instance) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.forceRedraw()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount a component and render the output.
|
* Mount a component and render the output.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useInput } from '@hermes/ink'
|
import { forceRedraw, useInput } from '@hermes/ink'
|
||||||
import { useStore } from '@nanostores/react'
|
import { useStore } from '@nanostores/react'
|
||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ import type { InputHandlerContext, InputHandlerResult } from './interfaces.js'
|
||||||
import { $isBlocked, $overlayState, patchOverlayState } from './overlayStore.js'
|
import { $isBlocked, $overlayState, patchOverlayState } from './overlayStore.js'
|
||||||
import { turnController } from './turnController.js'
|
import { turnController } from './turnController.js'
|
||||||
import { patchTurnState } from './turnStore.js'
|
import { patchTurnState } from './turnStore.js'
|
||||||
import { getUiState, patchUiState } from './uiStore.js'
|
import { getUiState } from './uiStore.js'
|
||||||
|
|
||||||
const isCtrl = (key: { ctrl: boolean }, ch: string, target: string) => key.ctrl && ch.toLowerCase() === target
|
const isCtrl = (key: { ctrl: boolean }, ch: string, target: string) => key.ctrl && ch.toLowerCase() === target
|
||||||
|
|
||||||
|
|
@ -380,8 +380,8 @@ export function useInputHandlers(ctx: InputHandlerContext): InputHandlerResult {
|
||||||
|
|
||||||
if (isAction(key, ch, 'l')) {
|
if (isAction(key, ch, 'l')) {
|
||||||
clearSelection()
|
clearSelection()
|
||||||
|
forceRedraw(terminal.stdout ?? process.stdout)
|
||||||
return patchUiState({})
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isVoiceToggleKey(key, ch)) {
|
if (isVoiceToggleKey(key, ch)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue