From e6dadab14349fd34eec63d5c8bf0e3fa55b0194c Mon Sep 17 00:00:00 2001 From: disqualifier Date: Fri, 26 Jun 2026 02:22:37 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20debug/echo=20command=20=E2=80=94=20prin?= =?UTF-8?q?t=20the=20spoken=20phrase=20to=20the=20console?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ' debug ' (alias echo) echoes what you said to the console as [VOICE] debug: "..." and injects nothing — a no-target test command for checking wake + STT transcription. added to the STT vocab so it's biased for. Signed-off-by: disqualifier --- README.md | 1 + src/claudedo/daemon.py | 3 +++ src/claudedo/grammar.py | 5 ++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d957f2..1592445 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ the wake phrase is optional. | `space []` (also `add [a] space`, `insert spaces`) | insert n spaces (default 1) | | `backspace []` (alias `delete`) | delete n chars (default 1), capped at the last submit boundary | | `erase` (alias `clear`/`wipe`) | delete everything typed since the last submit/boundary | +| `debug ` (alias `echo`) | just print what you said to the console (test wake/STT; injects nothing) | | `mode ptt` / `mode listen` | switch input mode | | `set ` (alias `sticky`/`switch`) | set the **sticky** target → `claude-` (persists) | | `target ` | **one-shot** override: run that command on `claude-` for this utterance only; sticky default unchanged | diff --git a/src/claudedo/daemon.py b/src/claudedo/daemon.py index c75c86b..b8ef966 100644 --- a/src/claudedo/daemon.py +++ b/src/claudedo/daemon.py @@ -193,6 +193,9 @@ class Daemon: sessions = target.list_sessions() self._console.emit(SYSTEM, "list -> " + (", ".join(sessions) if sessions else "(none running)")) return + if action.name == "debug": + self._console.emit(VOICE, f'debug: "{action.arg}"', "yellow") + return session, reason = target.resolve(parsed.one_shot, auto_target=cfg.auto_target) if session is None: diff --git a/src/claudedo/grammar.py b/src/claudedo/grammar.py index da27e2a..4ce27e4 100644 --- a/src/claudedo/grammar.py +++ b/src/claudedo/grammar.py @@ -44,6 +44,7 @@ _BACKSPACE_VERBS = ("backspace", "delete") _SPACE_VERBS = ("space", "spacebar") _ADD_VERBS = ("add", "insert") _ERASE_VERBS = ("erase", "clear", "wipe") +_DEBUG_VERBS = ("debug", "echo") _MODE_VERBS = ("mode",) _STICKY_VERBS = ("set", "sticky", "switch") _ONESHOT_VERBS = ("target",) @@ -55,7 +56,7 @@ _SELECT_VERBS = ("select", "option", "choose", "number") _COMMAND_WORDS = ( _YES_VERBS + _NO_VERBS + _APPROVE_VERBS + _DENY_VERBS + _SUBMIT_VERBS + _CANCEL_VERBS + _TYPE_VERBS + _BACKSPACE_VERBS + _SPACE_VERBS + _ADD_VERBS - + _ERASE_VERBS + _MODE_VERBS + _STICKY_VERBS + _ONESHOT_VERBS + _UNSET_VERBS + + _ERASE_VERBS + _DEBUG_VERBS + _MODE_VERBS + _STICKY_VERBS + _ONESHOT_VERBS + _UNSET_VERBS + _LIST_VERBS + _SELECT_VERBS + ("ptt", "listen") + ("one", "two", "three", "four") ) @@ -236,6 +237,8 @@ def match_command(remainder: str, threshold: float) -> Action | None: return Action("space", count) if _fuzzy_in(head, _ERASE_VERBS, threshold): return Action("erase") + if _fuzzy_in(head, _DEBUG_VERBS, threshold): + return Action("debug", " ".join(rest).strip()) if _fuzzy_in(head, _MODE_VERBS, threshold) and rest: if _fuzzy_in(rest[0], ("ptt",), threshold) or "push" in rest[0]: