feat(tui): add native terminal mode defaults
This commit is contained in:
@@ -205,6 +205,8 @@ def _add_top_level_flags(parser: argparse.ArgumentParser) -> None:
|
||||
help="Troubleshooting mode: disable ALL customizations — user config, AGENTS.md/memory injection, plugins, and MCP servers (implies --ignore-user-config and --ignore-rules)")
|
||||
inherited(parser, "--tui", action="store_true", default=False,
|
||||
help="Launch the modern TUI instead of the classic REPL")
|
||||
inherited(parser, "--native", "--tui-native", dest="tui_native", action="store_true", default=False,
|
||||
help="With --tui: use native terminal scrollback and disable mouse tracking")
|
||||
inherited(parser, "--cli", action="store_true", default=False,
|
||||
help="Force the classic prompt_toolkit REPL (overrides display.interface=tui)")
|
||||
inherited(parser, "--dev", dest="tui_dev", action="store_true", default=False,
|
||||
@@ -308,6 +310,8 @@ def _build_chat_parser(subparsers) -> argparse.ArgumentParser:
|
||||
help="Session source tag for filtering (default: cli). Use 'tool' for third-party integrations that should not appear in user session lists.")
|
||||
inherited(chat_parser, "--tui", action="store_true", default=SUPPRESS,
|
||||
help="Launch the modern TUI instead of the classic REPL")
|
||||
inherited(chat_parser, "--native", "--tui-native", dest="tui_native", action="store_true", default=SUPPRESS,
|
||||
help="Use native terminal scrollback and disable mouse tracking")
|
||||
inherited(chat_parser, "--cli", action="store_true", default=SUPPRESS,
|
||||
help="Force the classic prompt_toolkit REPL (overrides display.interface=tui)")
|
||||
inherited(chat_parser, "--dev", dest="tui_dev", action="store_true", default=SUPPRESS,
|
||||
|
||||
@@ -816,6 +816,9 @@ DEFAULT_CONFIG = {
|
||||
# Interface bare `hermes`/`hermes chat` launches: "cli" (prompt_toolkit REPL) | "tui" (Ink).
|
||||
# Flags win: `--cli` forces the REPL, `--tui` / HERMES_TUI=1 forces the TUI.
|
||||
"interface": "cli",
|
||||
# Native TUI uses the terminal's primary buffer and scrollback instead of the custom
|
||||
# alternate-screen viewport. Flags win: `--native` / `--tui-native` and `--cli`.
|
||||
"tui_native": False,
|
||||
# `hermes --tui` auto-resumes the most recent human-facing session (like `hermes -c`).
|
||||
# HERMES_TUI_RESUME=<id> always wins.
|
||||
"tui_auto_resume_recent": False,
|
||||
|
||||
@@ -289,7 +289,7 @@ def _wants_tui_early(argv: "list[str] | None" = None) -> bool:
|
||||
argv = sys.argv[1:]
|
||||
if "--cli" in argv:
|
||||
return False
|
||||
if os.environ.get("HERMES_TUI") == "1" or "--tui" in argv:
|
||||
if os.environ.get("HERMES_TUI") == "1" or any(flag in argv for flag in ("--tui", "--native", "--tui-native")):
|
||||
return True
|
||||
try:
|
||||
if not (sys.stdin.isatty() and sys.stdout.isatty()):
|
||||
@@ -1841,6 +1841,7 @@ def cmd_chat(args):
|
||||
_launch_tui(
|
||||
passthrough.pop("resume"),
|
||||
tui_dev=getattr(args, "tui_dev", False),
|
||||
native_mode=True if getattr(args, "tui_native", False) else None,
|
||||
model=getattr(args, "model", None),
|
||||
accept_hooks=getattr(args, "accept_hooks", False),
|
||||
**passthrough,
|
||||
|
||||
@@ -343,7 +343,8 @@ def _setup_tui_worktree() -> dict:
|
||||
|
||||
|
||||
def _launch_tui(
|
||||
resume_session_id: Optional[str] = None, tui_dev: bool = False, model: Optional[str] = None,
|
||||
resume_session_id: Optional[str] = None, tui_dev: bool = False, native_mode: Optional[bool] = None,
|
||||
model: Optional[str] = None,
|
||||
provider: Optional[str] = None, toolsets: object = None, skills: object = None,
|
||||
verbose: Optional[bool] = None, quiet: bool = False, query: Optional[str] = None,
|
||||
image: Optional[str] = None, worktree: bool = False, checkpoints: bool = False,
|
||||
@@ -373,6 +374,15 @@ def _launch_tui(
|
||||
os.close(active_session_fd)
|
||||
env["HERMES_TUI_ACTIVE_SESSION_FILE"] = active_session_file
|
||||
env.setdefault("NODE_ENV", "development" if tui_dev else "production")
|
||||
if native_mode is None:
|
||||
try:
|
||||
from hermes_cli.config import load_config
|
||||
from utils import is_truthy_value
|
||||
display = load_config().get("display", {})
|
||||
native_mode = is_truthy_value(display.get("tui_native", False)) if isinstance(display, dict) else False
|
||||
except Exception:
|
||||
native_mode = False
|
||||
env["HERMES_TUI_NATIVE"] = "1" if native_mode else "0"
|
||||
|
||||
wt_info = None
|
||||
if worktree:
|
||||
@@ -479,7 +489,7 @@ def _resolve_use_tui(args) -> bool:
|
||||
"""
|
||||
if getattr(args, "cli", False):
|
||||
return False
|
||||
if getattr(args, "tui", False):
|
||||
if getattr(args, "tui", False) or getattr(args, "tui_native", False):
|
||||
return True
|
||||
try:
|
||||
if not (sys.stdin.isatty() and sys.stdout.isatty()):
|
||||
|
||||
@@ -169,6 +169,11 @@ class TestParserFlags:
|
||||
args = self._parser().parse_args(["chat", "--tui"])
|
||||
assert args.tui is True
|
||||
|
||||
def test_native_flag_at_both_parser_levels(self):
|
||||
parser = self._parser()
|
||||
assert parser.parse_args(["--native"]).tui_native is True
|
||||
assert parser.parse_args(["chat", "--tui-native"]).tui_native is True
|
||||
|
||||
def test_cli_and_tui_are_relaunch_inherited(self):
|
||||
from hermes_cli.relaunch import _INHERITED_FLAGS_TABLE
|
||||
|
||||
@@ -176,6 +181,13 @@ class TestParserFlags:
|
||||
assert "--cli" in inherited
|
||||
assert "--tui" in inherited
|
||||
|
||||
def test_native_flag_is_relaunch_inherited(self):
|
||||
from hermes_cli.relaunch import _INHERITED_FLAGS_TABLE
|
||||
|
||||
inherited = {flag for flag, _takes_value in _INHERITED_FLAGS_TABLE}
|
||||
assert "--native" in inherited
|
||||
assert "--tui-native" in inherited
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# config default — shipped default preserves classic behavior
|
||||
|
||||
Reference in New Issue
Block a user