mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-27 01:11:40 +00:00
fix: handle empty sudo password and false prompts
This commit is contained in:
parent
a94099908a
commit
e22416dd9b
6 changed files with 293 additions and 35 deletions
34
cli.py
34
cli.py
|
|
@ -1546,6 +1546,7 @@ class HermesCLI:
|
|||
self._clarify_deadline = 0
|
||||
self._sudo_state = None
|
||||
self._sudo_deadline = 0
|
||||
self._modal_input_snapshot = None
|
||||
self._approval_state = None
|
||||
self._approval_deadline = 0
|
||||
self._approval_lock = threading.Lock()
|
||||
|
|
@ -6205,6 +6206,7 @@ class HermesCLI:
|
|||
timeout = 45
|
||||
response_queue = queue.Queue()
|
||||
|
||||
self._capture_modal_input_snapshot()
|
||||
self._sudo_state = {
|
||||
"response_queue": response_queue,
|
||||
}
|
||||
|
|
@ -6217,6 +6219,7 @@ class HermesCLI:
|
|||
result = response_queue.get(timeout=1)
|
||||
self._sudo_state = None
|
||||
self._sudo_deadline = 0
|
||||
self._restore_modal_input_snapshot()
|
||||
self._invalidate()
|
||||
if result:
|
||||
_cprint(f"\n{_DIM} ✓ Password received (cached for session){_RST}")
|
||||
|
|
@ -6231,6 +6234,7 @@ class HermesCLI:
|
|||
|
||||
self._sudo_state = None
|
||||
self._sudo_deadline = 0
|
||||
self._restore_modal_input_snapshot()
|
||||
self._invalidate()
|
||||
_cprint(f"\n{_DIM} ⏱ Timeout — continuing without sudo{_RST}")
|
||||
return ""
|
||||
|
|
@ -6403,6 +6407,33 @@ class HermesCLI:
|
|||
def _secret_capture_callback(self, var_name: str, prompt: str, metadata=None) -> dict:
|
||||
return prompt_for_secret(self, var_name, prompt, metadata)
|
||||
|
||||
def _capture_modal_input_snapshot(self) -> None:
|
||||
"""Temporarily clear the input buffer and save the user's in-progress draft."""
|
||||
if self._modal_input_snapshot is not None or not getattr(self, "_app", None):
|
||||
return
|
||||
try:
|
||||
buf = self._app.current_buffer
|
||||
self._modal_input_snapshot = {
|
||||
"text": buf.text,
|
||||
"cursor_position": buf.cursor_position,
|
||||
}
|
||||
buf.reset()
|
||||
except Exception:
|
||||
self._modal_input_snapshot = None
|
||||
|
||||
def _restore_modal_input_snapshot(self) -> None:
|
||||
"""Restore any draft text that was present before a modal prompt opened."""
|
||||
snapshot = self._modal_input_snapshot
|
||||
self._modal_input_snapshot = None
|
||||
if not snapshot or not getattr(self, "_app", None):
|
||||
return
|
||||
try:
|
||||
buf = self._app.current_buffer
|
||||
buf.text = snapshot.get("text", "")
|
||||
buf.cursor_position = min(snapshot.get("cursor_position", 0), len(buf.text))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _submit_secret_response(self, value: str) -> None:
|
||||
if not self._secret_state:
|
||||
return
|
||||
|
|
@ -7130,6 +7161,7 @@ class HermesCLI:
|
|||
# Sudo password prompt state (similar mechanism to clarify)
|
||||
self._sudo_state = None # dict with response_queue when active
|
||||
self._sudo_deadline = 0
|
||||
self._modal_input_snapshot = None
|
||||
|
||||
# Dangerous command approval state (similar mechanism to clarify)
|
||||
self._approval_state = None # dict with command, description, choices, selected, response_queue
|
||||
|
|
@ -7201,7 +7233,6 @@ class HermesCLI:
|
|||
text = event.app.current_buffer.text
|
||||
self._sudo_state["response_queue"].put(text)
|
||||
self._sudo_state = None
|
||||
event.app.current_buffer.reset()
|
||||
event.app.invalidate()
|
||||
return
|
||||
|
||||
|
|
@ -7406,7 +7437,6 @@ class HermesCLI:
|
|||
if self._sudo_state:
|
||||
self._sudo_state["response_queue"].put("")
|
||||
self._sudo_state = None
|
||||
event.app.current_buffer.reset()
|
||||
event.app.invalidate()
|
||||
return
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue