Skip to content

Reconnect the terminal after sleep, a network drop or an HA restart (2.5.3) - #84

Merged
ESJavadex merged 4 commits into
ESJavadex:mainfrom
nsleigh:fix/terminal-reconnect
Nov 6, 2026
Merged

ESJavadex merged 4 commits into
ESJavadex:mainfrom
nsleigh:fix/terminal-reconnect

Conversation

@nsleigh

@nsleigh nsleigh commented Nov 4, 2026 •

Copy link
Copy Markdown

Problem

After the computer sleeps or the network drops, the terminal often stops at
"Press ⏎ to Reconnect", and pressing Enter fails again. Only leaving the
dashboard and coming back works.

ttyd 1.7.7 retries a dropped connection once, straight away, then gives up.
That one try usually comes too early:

  • After sleep, Home Assistant's ingress session has often expired. Every
    request from the panel gets a 401 (the Supervisor log shows "No valid
    ingress session") until Home Assistant's page creates a new session.
  • During a Home Assistant restart, the add-on can't be reached at all (502).
  • A clean close (code 1000) is never retried by ttyd.

Fix

New image-service/public/terminal-reconnect.js, installed by index.html:

  • It watches the terminal frame for ttyd's "Press ⏎ to Reconnect" overlay.
  • While that shows, it checks the add-on's /health after 1, 2, 5, then
    every 10 s. It also checks at once when the browser comes back online or
    the tab is shown again.
  • When /health answers, it reloads the terminal frame, which reattaches to
    the same tmux session, so nothing running in it is lost.
  • Each step is logged to the browser console as [terminal-reconnect].

Also removes --client-option reconnect=5 from run.sh. ttyd 1.7.7 has
no reconnect option (only disableReconnect), so it did nothing.

Home Assistant restarts run by Claude

This helps most when Claude restarts Home Assistant itself, for example
after editing the configuration it checks it and runs ha core restart.
Before, the terminal dropped with "Press ⏎ to Reconnect" and you had to press
Enter (or reopen the panel) once Home Assistant was back, then see what
Claude had done meanwhile. Now the terminal comes back by itself as soon as
Home Assistant is up, showing Claude's session where it left off, so you can
watch it carry on and check the result. The same applies to a restart
started from Settings while the terminal is open.

Tests

tests/test-terminal-reconnect.js (7 tests, added to run-tests.sh) covers:
spotting the overlay, the retry delays, checking at once on online or a
shown tab, no reload if Enter already reconnected, and watching the new
document after a reload.

Tested

On Home Assistant OS, through ingress:

  • Home Assistant restart: retried through 502s while Core was down,
    then reloaded by itself. The released version needed Enter.
  • Sleep with an expired session: /health got 401 until Home
    Assistant's page created a new session, then the terminal reloaded by
    itself. This took between about 8 and 30 s: Home Assistant's page checks
    its session once a minute (ha-panel-app.ts), so the wait depends on
    when that check falls after waking.
  • A short sleep or Wi-Fi drop: ttyd's own retry still handles these; the
    new code doesn't act.

🤖 Generated with Claude Code

https://claude.ai/code/session_018rxd5pKHfU3wFULG6yLDE6

@nsleigh
nsleigh force-pushed the fix/terminal-reconnect branch from 17b0f53 to 8301c64 Compare November 5, 2026 08:50
…2.5.3)

ttyd 1.7.7 retries a dropped connection once and then stops at
"Press ⏎ to Reconnect". After sleep that try is refused (network not
back, or an expired ingress session answered with 401 until HA's page
creates a new one, up to a minute later), and during an HA restart the
add-on answers 502.

While ttyd shows that message, the panel checks /health after 1, 2, 5
and then every 10 s, and at once when the browser is back online or the
tab is shown. When the add-on answers, it reloads the terminal frame,
which reattaches to the same tmux session. So when Claude restarts
Home Assistant itself (e.g. ha core restart after a config change), the
terminal comes back by itself with Claude's session where it left off.

Also remove --client-option reconnect=5, which ttyd 1.7.7 ignores.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018rxd5pKHfU3wFULG6yLDE6
@nsleigh
nsleigh force-pushed the fix/terminal-reconnect branch from 8301c64 to aca83b5 Compare November 5, 2026 08:55
@nsleigh nsleigh changed the title Reconnect the terminal after sleep, a network drop or an HA restart (2.5.2) Reconnect the terminal after sleep, a network drop or an HA restart (2.5.3) Nov 5, 2026
@ESJavadex

Copy link
Copy Markdown
Owner

Thanks @nsleigh for this fix and for testing the sleep, network-drop and Home Assistant restart scenarios! The automatic recovery is a useful improvement.

I added commit 43bb363 to cover two additional edge cases: health requests now time out and abort after 10 seconds, and recovery keeps retrying if the iframe navigation fails after a successful health check. Three new regression tests cover stalled requests, error pages and navigation that never finishes.

Validation passed: all regression suites in a Linux container (including the image-service integration tests), metadata checks, ShellCheck, JavaScript syntax checks, and Chromium/WebKit browser tests. The reconnect suite now has 10 passing tests.

The merge is currently blocked by the required GitHub Actions checks: GitHub rejects workflow dispatch with “Actions has been disabled for this repository”, despite the Actions settings reporting enabled. The new commit has no CI checks yet. Auto-merge is also disabled. Once Actions can run again, the required checks can validate the commit and unblock merging.

@nsleigh

nsleigh commented Nov 6, 2026

Copy link
Copy Markdown
Author

Thanks for adding this. Both are real gaps: a hung /health request would
have stopped the retries, and nothing retried after a reload that didn't
bring the terminal back.

I've pulled 43bb363 and the reconnect suite (10 tests) and the full
regression suite pass here too. I'll rerun the sleep and HA restart tests on
my install with this commit and report back.

One small thing, not blocking: if /health answers but the terminal page
keeps failing to load (e.g. ttyd itself has died), the watchdog now reloads
the frame every 10 s for as long as the panel is open. Before, it left the
error page alone. It's cheap, but using the same 1/2/5/10 s steps (or
stopping after a few reloads) would avoid a steady reload loop. Happy to
leave it as is if you prefer.

@ESJavadex
ESJavadex enabled auto-merge November 6, 2026 21:15
@ESJavadex
ESJavadex merged commit 30c55ef into ESJavadex:main Nov 6, 2026
6 checks passed
@nsleigh
nsleigh deleted the fix/terminal-reconnect branch November 6, 2026 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants