Skip to content

feat: add --no-gui flag and fix win32 console crash#22928

Open
AlexFoxD wants to merge 389 commits into
NousResearch:mainfrom
AlexFoxD:fix/headless-mode-windows
Open

feat: add --no-gui flag and fix win32 console crash#22928
AlexFoxD wants to merge 389 commits into
NousResearch:mainfrom
AlexFoxD:fix/headless-mode-windows

Conversation

@AlexFoxD

Copy link
Copy Markdown

What does this PR do?

This PR introduces a Headless Mode via a new --no-gui (or -y) flag and implements automatic terminal detection. It solves the NoConsoleScreenBufferError on Windows when the agent is running in non-interactive environments (background processes, CI/CD, or automated Kanban workers) where a Win32 console buffer is unavailable.

Related Issue

Fixes # (если ты не создавал Issue, можешь оставить пустым или просто написать "None, encountered while using Kanban workers on Windows").

Type of Change

[x] 🐛 Bug fix (non-breaking change that fixes an issue)

[x] ✨ New feature (non-breaking change that adds functionality)

Changes Made

hermes_cli/main.py: Added --no-gui / -y flag to the CLI parser.

cli.py:

Implemented is_interactive() check using sys.stdout.isatty().

Wrapped _cprint in a try-except block to handle NoConsoleScreenBufferError.

Modified HermesCLI.run() to bypass prompt_toolkit and use a standard stdin loop when in headless mode.

Updated show_banner() to skip ASCII art in headless mode.

hermes_cli/kanban_db.py: Updated _default_spawn to automatically include the --no-gui flag when spawning background workers.

How to Test

Manual Test (Interactive): Run hermes chat. The TUI should work as usual.

Headless Test: Run echo "Hello" | hermes --no-gui chat. It should process the input and print plain text without attempting to initialize the GUI.

Background Test: Start a Kanban worker on Windows. It should now execute tasks without crashing with NoConsoleScreenBufferError.

Checklist

[x] I've read the Contributing Guide

[x] My commit messages follow Conventional Commits

[x] My PR contains only changes related to this fix

[x] I've tested on my platform: Windows 11 (или твоя версия)

Screenshots / Logs

Traceback before fix:

Python
prompt_toolkit.output.win32.NoConsoleScreenBufferError: No Windows console found. Are you running cmd.exe?

@AlexFoxD

Copy link
Copy Markdown
Author
  • Local Model Integration: Implemented support for local LLM providers to enhance autonomy and privacy.
  • Provider Updates: Modified runtime_provider.py (или где ты правил) to correctly initialize local models in headless environments.

@liuhao1024

Copy link
Copy Markdown
Contributor

One concern about the OPENAI_BASE_URL fallback added to _resolve_openrouter_runtime:

base_url = (
    (explicit_base_url or "").strip()
    or env_custom_base_url
    or os.getenv("OPENAI_BASE_URL", "").strip()   # ← new
    or (cfg_base_url.strip() if use_config_base_url else "")
    or env_openrouter_base_url
    or OPENROUTER_BASE_URL
)

This PR also adds openaicustom provider mapping, so users are now encouraged to use OPENAI_BASE_URL for their local OpenAI-compatible endpoints (Ollama, vLLM, etc.). But injecting that same env var into OpenRouter resolution means that if a user sets OPENAI_BASE_URL=https://localhost:11434/v1 for their local Ollama, all OpenRouter requests will silently route to localhost instead of openrouter.ai.

This is a semantic mismatch — OPENAI_BASE_URL is for OpenAI-compatible endpoints, not for OpenRouter. The env var should be OPENROUTER_BASE_URL (which already exists as env_openrouter_base_url in this same function) rather than reusing the OpenAI one.

Suggestion: Remove the OPENAI_BASE_URL fallback from _resolve_openrouter_runtime. If the intent is to allow overriding the OpenRouter base URL via env var, use a dedicated OPENROUTER_BASE_URL env var (or check if one already exists in env_openrouter_base_url).

Also noting: the package-lock.json / ui-tui/package-lock.json changes adding "peer": true to dozens of unrelated packages appear to be an npm install side effect — these may not belong in this PR.

@AlexFoxD

Copy link
Copy Markdown
Author

Done! I've refactored the PR according to your feedback:

Removed the OPENAI_BASE_URL fallback from _resolve_openrouter_runtime. You were absolutely right about the semantic mismatch; keeping it isolated prevents any accidental routing issues for OpenRouter users.

Cleaned up package-lock.json files by reverting them to the upstream/main state. Those changes were indeed an accidental side effect of my local environment setup.

Maintained the core fixes for the Windows NoConsoleScreenBufferError and the --no-gui flag.

Regarding local model support: I’m personally very interested in making Hermes more accessible for local-first workflows (Ollama, vLLM, etc.).

Quick question for the maintainers: Would you be open to a separate, dedicated PR for formal local LLM provider support in the future? Or do you prefer to keep the provider list strictly limited to cloud/official APIs for now? I’d love to hear your thoughts on the best way to contribute this feature without cluttering the existing architecture.

Thanks again for the detailed review!

@austinpickett austinpickett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix merge conflicts and resolve Copilot comments

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new --no-gui (“headless”) execution mode intended to avoid prompt_toolkit/console initialization in non-interactive environments (notably Windows background/CI contexts) and updates worker spawning to opt into that mode.

Changes:

  • Add a top-level --no-gui flag and plumb it through hermes_cli.maincli.mainHermesCLI.
  • Make _cprint safer in non-interactive/Win32 console-missing scenarios by falling back to plain print().
  • Force Kanban background workers to spawn Hermes with --no-gui.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
web/package-lock.json Lockfile updated (adds many "peer": true entries).
hermes_cli/main.py Passes parsed --no-gui into the classic CLI entrypoint as headless.
hermes_cli/kanban_db.py Adds --no-gui to spawned Kanban worker command line.
hermes_cli/auth.py Changes provider aliasing (adds openai → custom).
hermes_cli/_parser.py Adds CLI flag definition for -y/--no-gui.
cli.py Implements headless run loop + non-interactive-safe printing changes.
agent/auxiliary_client.py Expands auxiliary provider alias mapping (e.g. openai/ollama/vllm/... → custom).
Files not reviewed (1)
  • web/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hermes_cli/_parser.py
Comment thread hermes_cli/_parser.py Outdated
Comment thread cli.py
Comment thread cli.py Outdated
Comment thread cli.py Outdated
Comment on lines +11214 to +11215
print("Running in headless mode...")
import sys
Comment thread cli.py Outdated
print("Running in headless mode...")
import sys
for line in sys.stdin:
line = line.strip()
Comment thread hermes_cli/auth.py Outdated
"go": "opencode-go", "opencode-go-sub": "opencode-go",
"kilo": "kilocode", "kilo-code": "kilocode", "kilo-gateway": "kilocode",
"lmstudio": "lmstudio", "lm-studio": "lmstudio", "lm_studio": "lmstudio",
"openai": "custom",
Comment thread agent/auxiliary_client.py Outdated
Comment on lines +159 to +167
"tokenhub": "tencent-tokenhub",
"tencent-cloud": "tencent-tokenhub",
"tencentmaas": "tencent-tokenhub",
"openai": "custom",
"ollama": "custom",
"vllm": "custom",
"llamacpp": "custom",
"llama.cpp": "custom",
"llama-cpp": "custom",
Comment thread web/package-lock.json
Comment on lines 73 to 82
"node_modules/@babel/core": {
"version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
Comment thread cli.py

@AlexFoxD AlexFoxD left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make headless no-gui mode cleanup-safe

teknium1 and others added 14 commits May 21, 2026 23:03
…ult fallback (NousResearch#23585)

A YAML parse error in ~/.hermes/config.yaml caused load_config() to print
one line to stdout (Warning: Failed to load config: ...) and silently fall
back to DEFAULT_CONFIG, dropping every user override (auxiliary providers,
fallback chain, model settings). Users only noticed when downstream
behavior misbehaved — see issue NousResearch#23570 where a tab-indent error in the
auxiliary section caused aux fallback to use OpenRouter (depleted) instead
of the configured Codex/MiniMax chain.

Now: log at WARNING (so 'hermes logs' surfaces it), write a prominent line
to stderr, dedup on (path, mtime_ns, size) so concurrent loads don't spam,
and re-warn after the user edits the file. Both call sites (raw read +
merged load) route through the same helper.

Refs NousResearch#23570
Restate the trust model from first principles: the OS is the only
load-bearing boundary against an adversarial LLM. Distinguish
terminal-backend isolation (sandboxes the shell tool) from
whole-process wrapping (sandboxes the agent itself, reference
deployment NVIDIA OpenShell). Name in-process components (approval
gate, output redaction, Skills Guard) as heuristics, and the class
of reports that defeat them as out of scope under this policy —
while explicitly welcoming them as regular issues or PRs.

Introduce 'agent-loaded content' as the narrow, honest commitment:
attacker-influenced input must not chain into a write the agent
later loads on its own initiative.

Strip implementation-detail enumerations (backend names, adapter
names, config keys, env vars, internal symbols) so the doc stays
evergreen as code evolves.
5 commands: quote, search, history, compare, crypto
Zero dependencies, Python stdlib only.
Supports multi-symbol queries and crypto prices.
When the Discord typing API call fails (rate limit, network error, 403),
_typing_loop returns early but the stale task remains in _typing_tasks.
Subsequent send_typing calls see the stale entry and skip, leaving no
typing indicator for the rest of the agent invocation.

Add finally block to _typing_loop to always remove the task from
_typing_tasks on exit, whether from cancellation, error, or normal
completion. This allows send_typing to create a fresh task.

3 new tests in test_discord_send.py:
- Task removed after API error
- Typing restartable after failure
- stop_typing cleans up
…er-call retry storms (NousResearch#23597)

When an auxiliary provider returns HTTP 402 (credit / payment), every
subsequent compression / title-gen / session-search / vision call still
re-tried it as the FIRST entry in the chain — burning ~1 RTT to hit 402
again, then falling back. On a long Discord/LCM session that meant dozens
of doomed 402s per minute (issue NousResearch#23570).

Add a per-process unhealthy-provider cache with a 10 min TTL. When any
caller observes a payment error against a provider, the label is marked
unhealthy and skipped by:
  * _resolve_auto Step-1 (main provider use-as-aux path)
  * _resolve_auto Step-2 (aggregator/fallback chain)
  * _try_payment_fallback (used by call_llm/acall_llm on first 402)

Skip-logs are throttled to once per minute per label so a bursty session
doesn't spam agent.log. Entries auto-expire so a topped-up account
recovers without manual intervention. The cache is in-process only by
design — multi-profile users with different keys per profile must each
hit the 402 once.

Refs NousResearch#23570
Two independent opt-in QoL toggles, both off by default.

terminal.docker_extra_args:
- List of extra flags appended verbatim to docker run after security
  defaults. Useful for adding capabilities (e.g. --cap-add SETUID) or
  other docker run options not exposed by existing config keys.
- Non-string entries are logged and skipped.
- Also available via TERMINAL_DOCKER_EXTRA_ARGS='[...]' env var.

display.timestamps:
- Appends [HH:MM] to user input bullet and the assistant response box
  header. Single hub in _format_submitted_user_message_preview()
  covers both single-line and multi-line user previews; assistant
  response label gets the timestamp at box-open time.

Closes NousResearch#1569 (timestamps).

Co-authored-by: Mibayy <Mibayy@users.noreply.github.com>
…#21818)

Declares hindsight-client as an optional dependency group [hindsight]
in pyproject.toml. This allows build-time inclusion for environments
where runtime pip install is not possible (NixOS sealed venvs, Docker,
Kubernetes).

Not included in [all] — memory providers are plugins and should be
opted into explicitly.

Install via:
  uv sync --extra hindsight
  pip install hermes-agent[hindsight]

NixOS (with extraDependencyGroups):
  services.hermes-agent.extraDependencyGroups = [ "hindsight" ];

Closes NousResearch#8873
…arch#21817)

Expose the dependency-groups parameter from python.nix through
hermes-agent.nix and the NixOS module, allowing users to opt into
pyproject.toml optional extras (e.g. hindsight, voice, matrix) that
are resolved by uv inside the sealed venv.

Unlike extraPythonPackages (which appends to PYTHONPATH and requires
collision checking), extraDependencyGroups resolves the full dependency
graph in a single uv pass — no PYTHONPATH patching, no version
conflicts, no collision risk.

When to use which:
- extraDependencyGroups: enable a pyproject.toml optional extra
- extraPythonPackages: add an external Python plugin not in pyproject.toml

Usage:
  services.hermes-agent.extraDependencyGroups = [ "hindsight" ];

Or via overlay:
  pkgs.hermes-agent.override { extraDependencyGroups = [ "hindsight" ]; }

Refs: NousResearch#8873, NousResearch#9194
…NousResearch#23633)

The container entrypoint ran `chown -R` on $HERMES_HOME every start.
`chown` strips the setgid bit (kernel security behavior), destroying
the 2770 permissions the NixOS activation script sets for group access
by hostUsers. This caused PermissionError for interactive CLI users
even though they were in the hermes group.

Replace with `find ... ! -user $UID -exec chown` which only touches
files with wrong ownership, leaving correctly-owned directories and
their permission bits intact.

Affects: container.enable + container.hostUsers + addToSystemPackages

Related: NousResearch#19795, NousResearch#19788, NousResearch#9383
teknium1 and others added 27 commits May 21, 2026 23:14
Maps mr@shu.io to the mrshu GitHub handle so the release script
attributes the salvaged ACP approval bridging commit correctly.
Pre-stages AUTHOR_MAP for 12 new contributors whose PRs are being salvaged
in the upcoming batch:

- 1RB        (NousResearch#25462)
- ayushere   (NousResearch#25342)
- domtriola  (NousResearch#25424)
- ephron-ren (NousResearch#25358)
- freqyfreqy (NousResearch#25423)
- fu576      (NousResearch#25369)
- kfa-ai     (NousResearch#25398)
- magic524   (NousResearch#25361)
- PaTTeeL    (NousResearch#25359)
- pearjelly  (NousResearch#25388)
- raymaylee  (NousResearch#25394)
- Tianyu199509 (NousResearch#25421)
The word "worktree" (a git subcommand feature for parallel checkouts)
was used interchangeably with "repository" in the LSP docs, causing
confusion. LSP only requires a git-initialized directory, not an actual
worktree.

Fixes two instances: section "When LSP runs" and the troubleshooting
"Editing a file outside any git repo" heading.
Xiaomi MiMo emits reasoning via OpenAI's reasoning_content field and
requires reasoning_content on every assistant tool-call message when
replaying history. Without echo-back, subsequent API calls fail with
HTTP 400 — same shape as DeepSeek and Kimi/Moonshot thinking modes.

Adds _needs_mimo_tool_reasoning() detection (provider == 'xiaomi',
'mimo' in model, or xiaomimimo.com base url) and wires it into the
_needs_thinking_reasoning_pad() check.

Salvage of NousResearch#25358 by @ephron-ren (manually re-applied — original branch
was severely stale against current main).
Discord introduced message_snapshots for forwarded messages — text and
attachments live inside snap.content / snap.attachments rather than on
the parent message. _handle_message wasn't reading them, so forwards
showed up empty.

Defensively extracts snapshot text (when raw_content is empty) and
appends snapshot attachments to the working all_attachments list used
for type detection and media routing. hasattr/getattr guards keep this
safe on older discord.py installs without the field.

Salvage of NousResearch#25462 by @1RB (manually re-applied — original branch was
stale against current main).
When the auxiliary client fallback chain reaches a provider that has no
credentials configured (no API key, no pool entry), the current code
just returns (None, None) which counts toward the per-call timeout
budget on the next attempt. Mark the provider unhealthy with a short
TTL so the chain advances quickly to the next viable option.

Closes NousResearch#25384.

Salvage of NousResearch#25395 by @AllynSheep.
- _read_process_cmdline: /proc and 'ps' are unavailable on Windows,
  so process cmdline was always empty. Add psutil fallback (already
  a hard dependency used by _pid_exists in the same module).

- _record_looks_like_gateway: argv paths use backslashes on Windows
  but patterns use forward slashes/dots, so the fallback record check
  always failed. Normalize backslashes to forward slashes before
  matching.

Together these caused get_running_pid() to return None on Windows
even when the gateway process is alive, making the dashboard report
gateway as 'stopped' despite it functioning normally.
…t manager

The Feishu adapter wrapped lark-oapi's Connect() callable to inject
ping_interval/ping_timeout overrides, but made the wrapper async. The
underlying library uses Connect() as an async context manager (async
with Connect(...) as ws:), which requires the call itself to be sync
and return an AsyncContextManager — making it async meant the wrapper
was awaited eagerly and ws never bound.

Restoring the sync wrapper preserves the protocol while still injecting
the overrides.

Salvage of NousResearch#25388 by @pearjelly (manually re-applied — original branch
was severely stale against current main).
Cross-provider delegation (e.g. MiniMax parent → DeepSeek child) must not
inherit the parent's api_mode, because each provider uses a different API
surface: MiniMax uses 'anthropic_messages' while DeepSeek uses
'chat_completions'. Inheriting the wrong mode causes 404 errors.

When the effective provider differs from the parent's provider, derive
api_mode from the target provider's defaults instead (None triggers
re-derivation).

Refs: Bug NousResearch#20558, PR NousResearch#20563
…-length detection

When auxiliary.compression.provider is "auto", the compression model
reuses the main model's provider and base_url.  The main model's
context_length was correctly picking up custom_providers per-model
overrides (via _custom_providers stored during __init__), but the
auxiliary compression model's context-length detection path in
_check_compression_model_feasibility was not passing custom_providers,
causing it to skip step 0b and fall through to models.dev.

This meant that for providers like NVIDIA NIM where the user has a
per-model context_length in custom_providers (e.g. 196608 for
minimax-m2.7), the auxiliary model would use the models.dev value
(204800) instead of the user-configured one — a subtle discrepancy
that could lead to silent compression issues when the auxiliary model
doesn't actually support the detected context length.

Fix: pass self._custom_providers (already stored as an instance attr
during __init__) to the get_model_context_length() call for the
auxiliary compression model.
Background review fork redirected stdout/stderr around run_conversation()
so its iteration messages stay silent.  But the memory-provider teardown
(shutdown_memory_provider() and review_agent.close()) fired in the outer
finally block AFTER the redirect_stdout context exited — so provider
teardown prints (Honcho disconnect, Hindsight sync, etc.) leaked into
the parent terminal at end of every turn.

Moves the teardown inside the redirect_stdout scope on the success path
(and nulls review_agent so the finally safety-net skips double-shutdown).
The finally block is rewritten as an exception-path safety net that
re-opens a devnull redirect, since the original 'with' context has
already exited by the time finally runs.

Salvage of NousResearch#25342 by @ayushere (manually re-applied + merged conflict
with current main's set_thread_tool_whitelist wiring).
Add NovitaAI as a first-class provider with dedicated model selection
flow, live pricing, and authoritative context length resolution.

- Register provider in PROVIDER_REGISTRY, HERMES_OVERLAYS, and all
  alias/label maps (ID: novita, aliases: novita-ai, novitaai)
- Add dedicated _model_flow_novita() with 3-tier model list fallback:
  Novita API → models.dev → static curated list
- Fetch live pricing from /v1/models with correct unit conversion
  (input_token_price_per_m is 0.0001 USD per Mtok)
- Add Novita-specific context length resolution (step 4b) in
  get_model_context_length(), prioritized over models.dev/OpenRouter
- Register api.novita.ai in _URL_TO_PROVIDER to prevent early return
  from the custom-endpoint code path
- Add models.dev mapping (novita → novita-ai)
- Add default auxiliary model (deepseek/deepseek-v3-0324)
- Add NOVITA_API_KEY to test isolation (conftest.py)
- Update docs: providers page, env vars reference, CLI reference,
  .env.example, README, and landing page
…ntry

Follow-up to Alex-wuhu's NovitaAI provider commit. Adds:

- _pricing_cache hit/write in _fetch_novita_pricing (was missing — every
  pricing fetch was re-hitting the network), mirroring the
  fetch_ai_gateway_pricing pattern. force_refresh now also propagates
  from get_pricing_for_provider.
- TestNovitaProvider in tests/hermes_cli/test_api_key_providers.py
  covering profile load, alias resolution, registry auto-registration,
  model list parity between main.py and models.py, _URL_TO_PROVIDER,
  _PROVIDER_PREFIXES, context_size in _CONTEXT_LENGTH_KEYS, pricing
  unit conversion, and pricing cache behavior.
- AUTHOR_MAP entry for yanglongwei06@gmail.com → @Alex-yang00.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Removed custom provider mappings for OpenAI and related models.
Introduce _run_headless_loop(stdin=None) to process newline-delimited prompts in --no-gui mode (preserves leading/trailing spaces, skips blank lines, sets _agent_running around chat and correctly propagates interrupts/errors).

Add _finalize_run() to centralize CLI shutdown logic: mark exit, interrupt running agent, shutdown voice recorder, cleanup temp recordings, unregister callbacks, close session DB, invoke on_session_end hook for interrupted sessions, run global cleanup and print exit summary. Replace duplicated cleanup blocks by calling _finalize_run() from run() and error paths.

Tests updated: import io and pytest; new TestHeadlessRun validates headless input handling and ensures finalize is called on normal completion and on exceptions.
@AlexFoxD

Copy link
Copy Markdown
Author

Hi! I’m trying to finish resolving the conflicts on this PR, but rebasing onto the latest upstream/main keeps surfacing a large number of unrelated conflicts across files that are outside the scope of this change, such as release scripts, tests, Nix files, package-lock files, and run_agent.py.

This PR is intended to only address the Windows/headless --no-gui CLI behavior.

Would you prefer that I continue resolving all remaining rebase conflicts one by one, taking upstream/main for unrelated files, or should I rebuild the PR as a clean branch from upstream/main and re-apply only the focused headless/no-gui changes?

My preference would be to rebuild a clean branch to avoid carrying unrelated history/noise, but I’m happy to follow the maintainers’ preferred workflow.
Screenshot 2026-05-22 at 2 38 11 AM

@AlexFoxD AlexFoxD requested a review from austinpickett May 25, 2026 10:35

@austinpickett austinpickett left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request Changes

The core Win32 NoConsoleScreenBufferError fix and the --no-gui headless flag are genuinely needed — confirmed neither is on main — and the _cprint defensiveness is clean. However several issues must be resolved before merge:

🔴 Blockers:

  1. "openai" → "openrouter" alias in auth.py — Users explicitly passing --provider openai expecting native OpenAI API behavior would silently be routed to OpenRouter, consuming OpenRouter credits at a different endpoint. Remove this alias.

  2. Out-of-scope TUI staleness functions (_find_bundled_tui, _tui_build_needed, _hermes_ink_bundle_stale in hermes_cli/main.py) — these 93 lines walk the filesystem and check mtimes; unrelated to the --no-gui/Win32 fix, and conflict with #32227 which also touches hermes_cli/main.py. Please remove.

  3. Stray Cyrillic character in kanban_db.py comment: # quoting ambiguity ...Ы — accidental noise. Remove.

  4. Removed Dockerfile test (test_dockerfile_materializes_local_tui_ink_package) — a prior reviewer noted this test verified a runtime contract. Replace or justify its removal.

  5. Rebase needed — author offered to rebuild as clean branch; please rebase on current main.

  6. No CI — zero checks on record.

Once these are resolved, happy to re-approve the Win32 + --no-gui portions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.