diff --git a/hermes_cli/_parser.py b/hermes_cli/_parser.py index 9cc3c2779006..a4027221de4a 100644 --- a/hermes_cli/_parser.py +++ b/hermes_cli/_parser.py @@ -160,6 +160,12 @@ def build_top_level_parser(): default=None, help="Resume a previous session by ID or title", ) + parser.add_argument( + "--no-restore-cwd", + action="store_true", + default=False, + help="Don't cd into a resumed session's recorded working directory.", + ) parser.add_argument( "--continue", "-c", @@ -331,6 +337,12 @@ def build_top_level_parser(): default=argparse.SUPPRESS, help="Resume a previous session by ID (shown on exit)", ) + chat_parser.add_argument( + "--no-restore-cwd", + action="store_true", + default=argparse.SUPPRESS, + help="Don't cd into a resumed session's recorded working directory.", + ) chat_parser.add_argument( "--continue", "-c", diff --git a/hermes_cli/main.py b/hermes_cli/main.py index bcdfbe662a74..f10fef3fd958 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -2286,6 +2286,27 @@ def cmd_chat(args): # If resolution fails, keep the original value — _init_agent will # report "Session not found" with the original input + # Session<->workspace binding: cd back into a resumed session's recorded cwd + # so it resumes in the repo it belonged to. Opt out with --no-restore-cwd; + # skipped under --worktree (that path owns its own dir). Best-effort — a + # missing dir warns and stays put rather than failing the resume. + if ( + getattr(args, "resume", None) + and not getattr(args, "no_restore_cwd", False) + and not getattr(args, "worktree", False) + ): + try: + from hermes_state import SessionDB + + _saved_cwd = ((SessionDB().get_session(args.resume) or {}).get("cwd") or "").strip() + if _saved_cwd and not os.path.isdir(_saved_cwd): + print(f"⚠ session's recorded dir is gone ({_saved_cwd}); staying in {os.getcwd()}") + elif _saved_cwd and os.path.realpath(_saved_cwd) != os.path.realpath(os.getcwd()): + os.chdir(_saved_cwd) + print(f"↪ restored workspace dir: {_saved_cwd}") + except Exception: + pass # never let cwd-restore break a resume + # xAI retirement warning — one-shot, non-blocking, never fails startup try: from hermes_cli.xai_retirement import (