mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 06:51:16 +08:00
fix(tui): align Ctrl+L and /model with classic CLI semantics
Make Ctrl+L non-destructive by redrawing the current screen state instead of starting a new session, and stop auto-appending --global for typed /model commands so session scope remains the default unless explicitly requested.
This commit is contained in:
@@ -26,6 +26,11 @@ describe('constants', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('documents Ctrl/Cmd+L as non-destructive redraw', () => {
|
||||
expect(HOTKEYS.some(([, d]) => d === 'redraw / repaint')).toBe(true)
|
||||
expect(HOTKEYS.some(([, d]) => d.includes('new session'))).toBe(false)
|
||||
})
|
||||
|
||||
it('TOOL_VERBS maps known tools (verb-only, no emoji)', () => {
|
||||
expect(TOOL_VERBS.terminal).toBe('terminal')
|
||||
expect(TOOL_VERBS.read_file).toBe('reading')
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('createSlashHandler', () => {
|
||||
expect(ctx.gateway.gw.request).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('persists typed /model switches by default', async () => {
|
||||
it('keeps typed /model switches session-scoped by default', async () => {
|
||||
patchUiState({ sid: 'sid-abc' })
|
||||
|
||||
const ctx = buildCtx({
|
||||
@@ -40,7 +40,7 @@ describe('createSlashHandler', () => {
|
||||
expect(ctx.gateway.rpc).toHaveBeenCalledWith('config.set', {
|
||||
key: 'model',
|
||||
session_id: 'sid-abc',
|
||||
value: 'x-model --global'
|
||||
value: 'x-model'
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -16,17 +16,9 @@ import { patchOverlayState } from '../../overlayStore.js'
|
||||
import { patchUiState } from '../../uiStore.js'
|
||||
import type { SlashCommand } from '../types.js'
|
||||
|
||||
const GLOBAL_MODEL_FLAG_RE = /(?:^|\s)--global(?:\s|$)/
|
||||
|
||||
const TUI_SESSION_MODEL_RE = new RegExp(`(?:^|\\s)${TUI_SESSION_MODEL_FLAG}(?:\\s|$)`)
|
||||
const TUI_SESSION_STRIP_RE = new RegExp(`\\s*${TUI_SESSION_MODEL_FLAG}\\b\\s*`, 'g')
|
||||
|
||||
const persistedModelArg = (arg: string) => {
|
||||
const trimmed = arg.trim()
|
||||
|
||||
return !trimmed || GLOBAL_MODEL_FLAG_RE.test(trimmed) ? trimmed : `${trimmed} --global`
|
||||
}
|
||||
|
||||
const stripTuiSessionFlag = (trimmed: string) =>
|
||||
trimmed.replace(TUI_SESSION_STRIP_RE, ' ').replace(/\s+/g, ' ').trim()
|
||||
|
||||
@@ -41,7 +33,7 @@ const modelValueForConfigSet = (arg: string) => {
|
||||
return stripTuiSessionFlag(trimmed)
|
||||
}
|
||||
|
||||
return persistedModelArg(trimmed)
|
||||
return trimmed
|
||||
}
|
||||
|
||||
export const sessionCommands: SlashCommand[] = [
|
||||
|
||||
@@ -379,13 +379,8 @@ export function useInputHandlers(ctx: InputHandlerContext): InputHandlerResult {
|
||||
}
|
||||
|
||||
if (isAction(key, ch, 'l')) {
|
||||
if (actions.guardBusySessionSwitch()) {
|
||||
return
|
||||
}
|
||||
|
||||
patchUiState({ status: 'forging session…' })
|
||||
|
||||
return actions.newSession()
|
||||
clearSelection()
|
||||
return patchUiState(state => ({ ...state }))
|
||||
}
|
||||
|
||||
if (isVoiceToggleKey(key, ch)) {
|
||||
|
||||
@@ -19,7 +19,7 @@ export const HOTKEYS: [string, string][] = [
|
||||
...copyHotkeys,
|
||||
[action + '+D', 'exit'],
|
||||
[action + '+G / Alt+G', 'open $EDITOR (Alt+G fallback for VSCode/Cursor)'],
|
||||
[action + '+L', 'new session (clear)'],
|
||||
[action + '+L', 'redraw / repaint'],
|
||||
[paste + '+V / /paste', 'paste text; /paste attaches clipboard image'],
|
||||
['Tab', 'apply completion'],
|
||||
['↑/↓', 'completions / queue edit / history'],
|
||||
|
||||
Reference in New Issue
Block a user