fix(desktop): keep composer usable during reconnect (#45488)

* feat(cli): add --safe-mode troubleshooting flag

Inspired by Claude Code v2.1.169 (June 2026): run Hermes with all
customizations disabled to isolate setup problems from product bugs.

--safe-mode implies --ignore-user-config and --ignore-rules, and
additionally skips plugin discovery (hermes_cli/plugins.py) and MCP
server loading (tools/mcp_tool.py) via the internal HERMES_SAFE_MODE
env bridge.

* fix(desktop): keep composer usable during reconnect
This commit is contained in:
Teknium
2026-06-13 02:36:09 -07:00
committed by GitHub
parent b62e57b2f4
commit 8cf9d8689d
11 changed files with 246 additions and 26 deletions
+14
View File
@@ -213,6 +213,13 @@ def build_top_level_parser():
default=False,
help="Skip auto-injection of AGENTS.md, SOUL.md, .cursorrules, memory, and preloaded skills",
)
_inherited_flag(
parser,
"--safe-mode",
action="store_true",
default=False,
help="Troubleshooting mode: disable ALL customizations — user config, AGENTS.md/memory injection, plugins, and MCP servers (implies --ignore-user-config and --ignore-rules)",
)
_inherited_flag(
parser,
"--tui",
@@ -366,6 +373,13 @@ def build_top_level_parser():
default=argparse.SUPPRESS,
help="Skip auto-injection of AGENTS.md, SOUL.md, .cursorrules, memory, and preloaded skills. Combine with --ignore-user-config for a fully isolated run.",
)
_inherited_flag(
chat_parser,
"--safe-mode",
action="store_true",
default=argparse.SUPPRESS,
help="Troubleshooting mode: disable ALL customizations — user config, AGENTS.md/memory injection, plugins, and MCP servers (implies --ignore-user-config and --ignore-rules). Use to isolate whether a problem comes from your setup or from Hermes itself.",
)
chat_parser.add_argument(
"--source",
default=None,
+14 -2
View File
@@ -2199,6 +2199,18 @@ def cmd_chat(args):
if getattr(args, "yolo", False):
os.environ["HERMES_YOLO_MODE"] = "1"
# --safe-mode: troubleshooting mode that disables ALL customizations.
# Inspired by Claude Code v2.1.169's --safe-mode (June 2026): run with a
# pristine environment to isolate whether a problem comes from the user's
# setup (config, rules files, plugins, MCP servers) or from Hermes itself.
# Implemented as a superset of --ignore-user-config + --ignore-rules plus
# plugin/MCP discovery suppression (HERMES_SAFE_MODE is checked by
# hermes_cli/plugins.py and tools/mcp_tool.py).
if getattr(args, "safe_mode", False):
os.environ["HERMES_SAFE_MODE"] = "1"
os.environ["HERMES_IGNORE_USER_CONFIG"] = "1"
os.environ["HERMES_IGNORE_RULES"] = "1"
# --ignore-user-config: make load_cli_config() / load_config() skip the
# user's ~/.hermes/config.yaml and return built-in defaults. Set BEFORE
# importing cli (which runs `CLI_CONFIG = load_cli_config()` at module
@@ -2256,8 +2268,8 @@ def cmd_chat(args):
"checkpoints": getattr(args, "checkpoints", False),
"pass_session_id": getattr(args, "pass_session_id", False),
"max_turns": getattr(args, "max_turns", None),
"ignore_rules": getattr(args, "ignore_rules", False),
"ignore_user_config": getattr(args, "ignore_user_config", False),
"ignore_rules": getattr(args, "ignore_rules", False) or getattr(args, "safe_mode", False),
"ignore_user_config": getattr(args, "ignore_user_config", False) or getattr(args, "safe_mode", False),
"compact": getattr(args, "compact", False),
}
# Filter out None values
+8
View File
@@ -1124,6 +1124,14 @@ class PluginManager:
"""
if self._discovered and not force:
return
# Safe mode (--safe-mode / HERMES_SAFE_MODE=1): troubleshooting run
# with all customizations disabled. Skip plugin discovery entirely so
# no third-party code (hooks, tools, platforms) loads. Mark as
# discovered so callers see a clean empty registry, not a retry loop.
if env_var_enabled("HERMES_SAFE_MODE"):
logger.info("HERMES_SAFE_MODE=1 — plugin discovery skipped")
self._discovered = True
return
if force:
self._plugins.clear()
self._hooks.clear()