Desktop app auto-approves dangerous commands in local chat — no approval prompt (Telegram shows one)
Summary
Hermes One desktop app silently auto-approves every dangerous command in local (dashboard) chat — no approval prompt is ever shown. In Telegram/Discord (gateway platforms) the same command shows inline approve buttons (once / session / always / deny). This defeats approvals.mode: manual on the desktop surface.
Evidence
The dashboard backend already implements the full approval protocol correctly:
tui_gateway/server.py_emit_approval_requestemits anapproval.requestWS event withchoices: ["once", "session", "always", "deny"](subset depending onallow_permanent).tui_gateway/methods_prompt.pyapproval.respondRPC resolves the pending approval viaresolve_gateway_approval(session_key, choice).
The desktop app then swallows it in src/main/hermes.ts:
- Local chat (TUI gateway WS) —
sendMessageViaTuiGateway:
if (event.type === "approval.request") {
// Match the existing local chat posture: Hermes One does not expose a
// mid-stream approval dialog, so answer the dashboard protocol once and
// keep the transcript focused on the resulting tool call/result events.
void client.request("approval.respond", {
session_id: activeSessionId,
choice: "once",
all: false,
}, 30_000)...Every approval is answered choice: "once" — the command runs with no user interaction.
- API-stream path —
openEventStream:
if (eventName === "approval.request") {
stopRunAndFallback();
}The run is stopped and the chat silently downgrades to plain completions.
- The renderer's Approve/Deny bar (
chat-approval-barin the chat chunk) is only wired to the legacy flow: it appears after a response finishes, gated by the text heuristicAPPROVAL_RE(/requires? (your )?approval|\/approve.*\/deny|.../). It is never triggered by the real mid-runapproval.requestevent.
Expected behavior
A visible approval prompt with the same choices the gateway platforms offer (approve once / approve for session / always allow / deny), shown mid-run when approval.request arrives, answered via approval.respond. The server protocol is already in place — this is an app-side UI gap.
Impact
approvals.mode: manualis silently ineffective on the desktop surface (commands inDANGEROUS_PATTERNSrun unattended).- Hardline blocks still apply, so this is not a full bypass — but every recoverable flagged command (curl|sh, chmod +x, sensitive-path writes, etc.) executes without consent.
Source: fathah/hermes-desktop