A short Web-Audio "ding-dong" when OpenClaw Control UI finishes a reply. Locally nicknamed echo.
A zero-build local patch for the OpenClaw Control UI (webchat) that plays a short two-tone chime (A5 → E5, ~900ms) when an assistant reply finishes streaming.
Think of it as the missing "reply ready" sound for OpenClaw's web UI — especially useful when you keep the Control UI in a background tab while you work elsewhere.
This is a stop-gap mirror of upstream
PR openclaw/openclaw#73894
(issue #69186) which
implements the same feature but has not been merged yet. echo-cue works
today and gracefully steps aside the moment upstream ships.
clawhub install echo-cue
bash $(clawhub list --json | jq -r '.[]|select(.slug=="echo-cue").path')/apply.shgit clone https://github.com/SymbolStar/echo-cue.git
cd echo-cue
bash apply.shThen refresh your Control UI browser tab. Click or press a key once on the page to unlock the AudioContext (browser policy — happens automatically the first time you send a message).
DevTools console:
window.__milly_cue_v1__ // → true// Disable entirely
localStorage.setItem('milly.completionCue', 'off')
// Re-enable
localStorage.removeItem('milly.completionCue')
// Limit ringing to hidden / unfocused tabs only (default in 0.2.0+: rings always)
localStorage.setItem('milly.completionCue.onlyHidden', 'on')
// Restore default (always rings)
localStorage.removeItem('milly.completionCue.onlyHidden')bash remove.shRestores the original bundle and index.html from the .milly.bak files.
The update overwrites dist/control-ui/..., dropping the patch. Re-run:
bash apply.shapply.sh is idempotent and upstream-aware:
- Already patched → skip
- Upstream
responseCompletionSoundshipped → skip + advise uninstall
- Detects every OpenClaw install on the box (Homebrew, nvm,
OPENCLAW_HOME) - Backs up the current Control UI bundle (
index-*.js → .milly.bak) - Appends a small IIFE that:
- Watches the chat container with a
MutationObserver - Listens for added
.chat-group.assistantnodes - Skips
NO_REPLY/ empty silent completions - Plays a Web Audio two-tone chime (A5 → E5)
- 4-second hard rate-limit + content-fingerprint dedup → no double-rings
- Watches the chat container with a
- Renames the bundle to
index-*.milly-NNN.jsand updatesindex.htmlso a plainCmd+Rrefresh actually picks up the patch (Vite's hashed bundles ship withCache-Control: immutable, otherwise hard-refresh would still hit cache)
- Anchor:
.chat-group.assistantDOM class. If OpenClaw renames it the patch silently does nothing (fail-quiet — no breakage). - AudioContext requires one user gesture per page load (browser policy).
- Webchat only. TUI / iOS / macOS / Android clients are not covered (they have their own native notification stacks).
- Single audible cue per assistant turn regardless of message length.
| File | Purpose |
|---|---|
SKILL.md |
ClawHub skill manifest (frontmatter name + description) |
apply.sh |
Detect every OpenClaw install, idempotent inject IIFE, backup, cache-bust |
remove.sh |
Restore from .milly.bak files |
inject/completion-cue.iife.js |
The patch payload |
tests/manual.md |
7-step verify checklist |
- ClawHub: https://clawhub.com/skills/echo-cue
- Upstream issue: openclaw/openclaw#69186
- Upstream PR (stop-gap target): openclaw/openclaw#73894
- Sibling skill (same patch pattern):
agent-tab-title
MIT — see LICENSE.