Merge branch 'main' of github.com:NousResearch/hermes-agent into feat/ink-refactor

This commit is contained in:
Brooklyn Nicholson 2026-04-14 18:26:05 -05:00
commit bf54f1fb2f
83 changed files with 5435 additions and 470 deletions

View file

@ -4283,7 +4283,40 @@ def cmd_update(args):
capture_output=True, text=True, timeout=15,
)
if restart.returncode == 0:
restarted_services.append(svc_name)
# Verify the service actually survived the
# restart. systemctl restart returns 0 even
# if the new process crashes immediately.
import time as _time
_time.sleep(3)
verify = subprocess.run(
scope_cmd + ["is-active", svc_name],
capture_output=True, text=True, timeout=5,
)
if verify.stdout.strip() == "active":
restarted_services.append(svc_name)
else:
# Retry once — transient startup failures
# (stale module cache, import race) often
# resolve on the second attempt.
print(f"{svc_name} died after restart, retrying...")
retry = subprocess.run(
scope_cmd + ["restart", svc_name],
capture_output=True, text=True, timeout=15,
)
_time.sleep(3)
verify2 = subprocess.run(
scope_cmd + ["is-active", svc_name],
capture_output=True, text=True, timeout=5,
)
if verify2.stdout.strip() == "active":
restarted_services.append(svc_name)
print(f"{svc_name} recovered on retry")
else:
print(
f"{svc_name} failed to stay running after restart.\n"
f" Check logs: journalctl --user -u {svc_name} --since '2 min ago'\n"
f" Restart manually: systemctl {'--user ' if scope == 'user' else ''}restart {svc_name}"
)
else:
print(f" ⚠ Failed to restart {svc_name}: {restart.stderr.strip()}")
except (FileNotFoundError, subprocess.TimeoutExpired):
@ -4371,6 +4404,8 @@ def _coalesce_session_name_args(argv: list) -> list:
"status", "cron", "doctor", "config", "pairing", "skills", "tools",
"mcp", "sessions", "insights", "version", "update", "uninstall",
"profile", "dashboard",
"honcho", "claw", "plugins", "acp",
"webhook", "memory", "dump", "debug", "backup", "import", "completion", "logs",
}
_SESSION_FLAGS = {"-c", "--continue", "-r", "--resume"}
@ -4666,17 +4701,20 @@ def cmd_dashboard(args):
host=args.host,
port=args.port,
open_browser=not args.no_open,
allow_public=getattr(args, "insecure", False),
)
def cmd_completion(args):
def cmd_completion(args, parser=None):
"""Print shell completion script."""
from hermes_cli.profiles import generate_bash_completion, generate_zsh_completion
from hermes_cli.completion import generate_bash, generate_zsh, generate_fish
shell = getattr(args, "shell", "bash")
if shell == "zsh":
print(generate_zsh_completion())
print(generate_zsh(parser))
elif shell == "fish":
print(generate_fish(parser))
else:
print(generate_bash_completion())
print(generate_bash(parser))
def cmd_logs(args):
@ -6182,13 +6220,13 @@ Examples:
# =========================================================================
completion_parser = subparsers.add_parser(
"completion",
help="Print shell completion script (bash or zsh)",
help="Print shell completion script (bash, zsh, or fish)",
)
completion_parser.add_argument(
"shell", nargs="?", default="bash", choices=["bash", "zsh"],
"shell", nargs="?", default="bash", choices=["bash", "zsh", "fish"],
help="Shell type (default: bash)",
)
completion_parser.set_defaults(func=cmd_completion)
completion_parser.set_defaults(func=lambda args: cmd_completion(args, parser))
# =========================================================================
# dashboard command
@ -6201,6 +6239,10 @@ Examples:
dashboard_parser.add_argument("--port", type=int, default=9119, help="Port (default 9119)")
dashboard_parser.add_argument("--host", default="127.0.0.1", help="Host (default 127.0.0.1)")
dashboard_parser.add_argument("--no-open", action="store_true", help="Don't open browser automatically")
dashboard_parser.add_argument(
"--insecure", action="store_true",
help="Allow binding to non-localhost (DANGEROUS: exposes API keys on the network)",
)
dashboard_parser.set_defaults(func=cmd_dashboard)
# =========================================================================