diff --git a/cli.py b/cli.py index 9d3bd17e94..a3c534365a 100644 --- a/cli.py +++ b/cli.py @@ -5483,6 +5483,13 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): self._slash_confirm_state = None self._slash_confirm_deadline = 0 self._model_picker_state = None + # Rotating task-oriented composer placeholder (C-09), chosen once per + # session so it stays stable while the empty input box is on screen. + try: + from hermes_cli.tips import get_random_composer_placeholder + self._composer_placeholder = get_random_composer_placeholder() + except Exception: + self._composer_placeholder = "" # Armed when a bare `/resume` prints the recent-sessions list so the # very next bare numeric input (e.g. `3`) resolves to that session. # Holds the exact list used for index resolution; one-shot (cleared on @@ -18801,7 +18808,11 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin, CLIBillingMixin): _stash_hint = "" if _stash_hint: return _stash_hint - return "" + # Idle + empty composer: show a rotating task-oriented example to + # nudge the user toward a high-value first action (C-09). Chosen + # once per session (self._composer_placeholder) so it stays stable + # while being read, not flickering every render. + return getattr(cli_ref, "_composer_placeholder", "") or "" input_area.control.input_processors.append(_PlaceholderProcessor(_get_placeholder)) diff --git a/hermes_cli/tips.py b/hermes_cli/tips.py index 1729444fd4..b2c8a041ab 100644 --- a/hermes_cli/tips.py +++ b/hermes_cli/tips.py @@ -483,3 +483,30 @@ def get_random_tip(exclude_recent: int = 0) -> str: deduplication across sessions. """ return random.choice(TIPS) + + +# --------------------------------------------------------------------------- +# Composer placeholders — short, task-oriented example prompts shown in the +# empty input box to nudge new users toward high-value first actions (C-09, +# inspired by opencode/codex rotating placeholders). Kept generic so they fit +# any project or none — Hermes is not a coding-only agent. +# --------------------------------------------------------------------------- + +COMPOSER_PLACEHOLDERS = [ + "Ask anything, or type / for commands…", + "Summarize what's in this folder", + "Draft a reply to the last email in my inbox", + "Plan a feature, then build it step by step", + "Find and fix a failing test", + "Research this topic and write me a brief", + "What changed in this repo recently?", + "Turn these notes into a to-do list", + "Explain this error and how to fix it", + "Set a reminder or schedule a recurring task", + "Type / to browse commands, or Ctrl+P for the palette", +] + + +def get_random_composer_placeholder() -> str: + """Return a rotating task-oriented placeholder for the empty composer.""" + return random.choice(COMPOSER_PLACEHOLDERS) diff --git a/tests/hermes_cli/test_composer_placeholder.py b/tests/hermes_cli/test_composer_placeholder.py new file mode 100644 index 0000000000..d2d62a3c8e --- /dev/null +++ b/tests/hermes_cli/test_composer_placeholder.py @@ -0,0 +1,13 @@ +"""Test for rotating task-oriented composer placeholders (C-09).""" + +from hermes_cli.tips import COMPOSER_PLACEHOLDERS, get_random_composer_placeholder + + +def test_composer_placeholders_nonempty(): + assert COMPOSER_PLACEHOLDERS + assert all(isinstance(p, str) and p.strip() for p in COMPOSER_PLACEHOLDERS) + + +def test_get_random_composer_placeholder_returns_a_member(): + for _ in range(20): + assert get_random_composer_placeholder() in COMPOSER_PLACEHOLDERS