Cron run output is never authored Markdown -- it is logs/JSON/plain text.
Using renderMd() with any heuristic or synthetic fence is fragile:
- Content starting with #, |, > becomes headings/tables/blockquotes
- Embedded triple-backtick in content breaks the synthetic fence
Fix: use DOM-created pre/code with textContent throughout:
- No heuristic, no synthetic fence -- every byte renders verbatim
- Both render paths (initial load + View full output) use the same approach
When viewing cron job run logs (prompt/response), the raw content
was passed through renderMd() which broke formatting for JSON and
plain text (single newlines collapsed, special chars interpreted).
Now detects if content looks like markdown and wraps raw content
in triple backticks so it renders as a proper code block with
preserved whitespace and formatting.
A threading.Timer per RequestDiagnostics spawns one OS thread per request, held
alive until finish() cancels it. Under sustained /api/sessions poll load this
exhausts the per-process thread cap (RuntimeError: can't start new thread) and
the server stops accepting connections. Replace with a single lazy-init
watchdog daemon thread that scans pending diags every ~1s; public API
unchanged. Caps timeout-tracking at 1 thread/process regardless of request rate.
AGENTS.md requires a CHANGELOG entry for user-visible behavior changes, and
this is one (a stale approval card went from a stuck "Approval response not
accepted." dead-end to clearing cleanly). The PR shipped the routes.js +
messages.js fix without a changelog note; this adds the [Unreleased] -> Fixed
entry crediting santastabber / b3nw, noting the #527 guard is preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On the default local in-process backend, an approval card whose stream
ended while still pending (cancel/fork/provider-error/completion) left the
agent queue entry dropped and the _pending mirror reconciled away. Clicking
Approve/Deny then sent an approval_id that matched nothing, so the handler
returned a bare {ok:false}; since #4771 the frontend surfaces that as
'Approval response not accepted.' with a stuck card (reported by
@santastabber on v0.51.666 and b3nw).
Distinguish a genuinely stale card (no pending approval for the session ->
benign {ok:true, stale_cleared:true} so the UI clears the orphan) from a
stale-id click made while a DIFFERENT approval is live (still ok:false so it
can never resolve the wrong command -- #527 guard preserved). Frontend
clears the orphan card on stale_cleared even if the displayed id drifted.
Co-authored-by: b3nw <b3nw@users.noreply.github.com>