hermes - 💡(How to fix) Fix [Bug]: hermes profile create generates unusable #!/bin/sh wrapper on Windows — should create .bat file [2 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fixed

Code Example

#!/bin/sh
exec hermes -p <name> "$@"

---

@echo off
hermes -p <name> %*

---

import platform as _platform
is_windows = _platform.system() == "Windows"
if is_windows:
    wrapper_path = wrapper_dir / f"{canon}.bat"
    content = f"@echo off\r\nhermes -p {canon} %*\r\n"
else:
    wrapper_path = wrapper_dir / canon
    content = f'#!/bin/sh\nexec hermes -p {canon} "$@"\n'
wrapper_path.write_text(content)
if not is_windows:
    wrapper_path.chmod(...)

---

is_windows = _platform.system() == "Windows"
candidates = [wrapper_dir / f"{canon}.bat"] if is_windows else []
candidates.append(wrapper_dir / canon)
for wrapper_path in candidates:
    if wrapper_path.exists():
        content = wrapper_path.read_text()
        if "hermes -p" in content:
            wrapper_path.unlink()
            return True

---

is_windows = _platform.system() == "Windows"
lookup_cmd = ["where", canon] if is_windows else ["which", canon]
result = subprocess.run(lookup_cmd, ...)
existing_path = result.stdout.strip().splitlines()[0]  # `where` returns multiple lines
our_wrapper = str(wrapper_dir / (f"{canon}.bat" if is_windows else canon))
RAW_BUFFERClick to expand / collapse

What's Going Wrong?

On Windows, hermes profile create <name> calls create_wrapper_script() in hermes_cli/profiles.py, which creates a POSIX shell script at ~/.local/bin/<name> with the content:

#!/bin/sh
exec hermes -p <name> "$@"

This file has no extension and uses a #!/bin/sh shebang, so Windows cannot execute it. The profile alias simply does not work.

Three functions in hermes_cli/profiles.py have no Windows-specific handling:

FunctionProblem on Windows
create_wrapper_script() (line ~359)Creates a #!/bin/sh shell script instead of a .bat file; calls chmod with POSIX execute bits
remove_wrapper_script() (line ~382)Only looks for the extensionless path, never finds <name>.bat
check_alias_collision() (line ~319)Calls ["which", name]which does not exist on Windows

Steps to Reproduce

  1. Install Hermes on Windows 11
  2. Run hermes profile create redqueen
  3. Observe ~/.local/bin/redqueen is created as a #!/bin/sh shell script
  4. Try running redqueen chat — command not found / no output on Windows

Expected Behaviour

On Windows, hermes profile create <name> should create ~/.local/bin/<name>.bat with:

@echo off
hermes -p <name> %*

remove_wrapper_script should also check for <name>.bat on Windows, and check_alias_collision should use where instead of which.

Fix Applied Locally

The following changes to hermes_cli/profiles.py resolve all three issues:

create_wrapper_script — detect Windows, write .bat, skip chmod:

import platform as _platform
is_windows = _platform.system() == "Windows"
if is_windows:
    wrapper_path = wrapper_dir / f"{canon}.bat"
    content = f"@echo off\r\nhermes -p {canon} %*\r\n"
else:
    wrapper_path = wrapper_dir / canon
    content = f'#!/bin/sh\nexec hermes -p {canon} "$@"\n'
wrapper_path.write_text(content)
if not is_windows:
    wrapper_path.chmod(...)

remove_wrapper_script — check .bat first on Windows:

is_windows = _platform.system() == "Windows"
candidates = [wrapper_dir / f"{canon}.bat"] if is_windows else []
candidates.append(wrapper_dir / canon)
for wrapper_path in candidates:
    if wrapper_path.exists():
        content = wrapper_path.read_text()
        if "hermes -p" in content:
            wrapper_path.unlink()
            return True

check_alias_collision — use where on Windows:

is_windows = _platform.system() == "Windows"
lookup_cmd = ["where", canon] if is_windows else ["which", canon]
result = subprocess.run(lookup_cmd, ...)
existing_path = result.stdout.strip().splitlines()[0]  # `where` returns multiple lines
our_wrapper = str(wrapper_dir / (f"{canon}.bat" if is_windows else canon))

Environment

  • OS: Windows 11 (10.0.26200)
  • Hermes version: 0.15.1
  • Python: 3.11
  • Shell: PowerShell

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix [Bug]: hermes profile create generates unusable #!/bin/sh wrapper on Windows — should create .bat file [2 pull requests]