feat: add /diff command to show git changes in working directory

Shows staged and unstaged changes in the current working directory.
/diff shows stat summary + full diff, /diff --stat shows summary only.

Uses git diff directly — no checkpoint system required. Works in any
git repository.

Closes #4250
This commit is contained in:
SHL0MS 2026-04-03 15:43:32 -04:00 committed by Teknium
parent 2078af601a
commit 88d45edca2
2 changed files with 64 additions and 0 deletions

62
cli.py
View file

@ -8024,6 +8024,66 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin):
return True
def _handle_diff_command(self, cmd: str):
"""Show git diff of changes in the current working directory."""
import subprocess as _sp
cwd = os.getenv("TERMINAL_CWD", os.getcwd())
parts = cmd.split()[1:]
stat_only = "--stat" in parts
# Check if we're in a git repo
try:
_sp.run(
["git", "rev-parse", "--is-inside-work-tree"],
cwd=cwd, capture_output=True, check=True, timeout=5,
)
except Exception:
_cprint(f" {_DIM}Not a git repository.{_RST}")
return
try:
# Show stat summary
stat_result = _sp.run(
["git", "diff", "--stat"],
cwd=cwd, capture_output=True, text=True, timeout=10,
)
staged_result = _sp.run(
["git", "diff", "--cached", "--stat"],
cwd=cwd, capture_output=True, text=True, timeout=10,
)
stat_out = stat_result.stdout.strip()
staged_out = staged_result.stdout.strip()
if not stat_out and not staged_out:
_cprint(f" {_DIM}No changes.{_RST}")
return
if staged_out:
_cprint(f"\n {_BOLD}Staged:{_RST}")
self.console.print(_rich_text_from_ansi(staged_out))
if stat_out:
_cprint(f"\n {_BOLD}Unstaged:{_RST}")
self.console.print(_rich_text_from_ansi(stat_out))
if stat_only:
return
# Show full diff
diff_result = _sp.run(
["git", "diff", "--cached"] if staged_out and not stat_out else ["git", "diff"],
cwd=cwd, capture_output=True, text=True, timeout=30,
)
diff_out = diff_result.stdout.strip()
if diff_out:
_cprint("")
self.console.print(_rich_text_from_ansi(diff_out))
except _sp.TimeoutExpired:
_cprint(f" {_DIM}Git diff timed out.{_RST}")
except Exception as e:
_cprint(f" {_DIM}Git diff error: {e}{_RST}")
def save_conversation(self):
"""Save the current conversation to a JSON snapshot under ~/.hermes/sessions/saved/.
@ -9688,6 +9748,8 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin):
self._status_bar_visible = not self._status_bar_visible
state = "visible" if self._status_bar_visible else "hidden"
self._console_print(f" Status bar {state}")
elif canonical == "diff":
self._handle_diff_command(cmd_original)
elif canonical == "battery":
self._handle_battery_command(cmd_original)
elif canonical == "timestamps":

View file

@ -151,6 +151,8 @@ COMMAND_REGISTRY: list[CommandDef] = [
CommandDef("timestamps", "Toggle [HH:MM] timestamps on messages and /history", "Configuration",
cli_only=True, args_hint="[on|off|status]",
subcommands=("on", "off", "status"), aliases=("ts",)),
CommandDef("diff", "Show git diff of changes in the current working directory", "Info",
cli_only=True, args_hint="[--stat]"),
CommandDef("verbose", "Cycle tool progress display: off -> new -> all -> verbose -> log",
"Configuration", cli_only=True,
gateway_config_gate="display.tool_progress_command"),