adom-desktop v1.4.11 follow-up — tab_not_found structured fields missing

Paste into Claude on the desktop. v1.4.10 shipped the WAGO Vue-Toastification fix (verified working — chip-fetcher's own creds modal modal-overlay.open is correctly detected as modalRoot:{id:creds-modal,cls:modal-overlay open,z:100} with pickStrategy:"modal-scoped-largest", real Generate-Datasheet flow's modal-detection misfire was a different test-setup issue, not a heuristic bug). 🎉

But the tab_not_found error structure is incomplete.


The bug

v1.4.10 release notes promise this shape:

{
  "ok": false,
  "errorCode": "tab_not_found",
  "error": "Tab \"tab-999\" not found in session \"chip-fetcher\".",
  "currentTabs": ["tab-1"],
  "lastKnownUrl": "https://...",
  "opener": "popup",
  "openerTabId": "tab-1",
  "closedMsAgo": 1842,
  "_hint": "This tab closed 2s ago at URL ... Call browser_fetch_url with that URL ..."
}

What v1.4.10 actually returns:

adom-desktop browser_eval '{"sessionId":"chip-fetcher","tabId":"tab-999","expr":"document.title"}'
# Exit 1
# {
#   "error": "Tab \"tab-999\" not found in session \"chip-fetcher\"."
# }

Only the error string. No ok:false, no errorCode, no currentTabs, no _hint, no ring-buffer data (lastKnownUrl / opener / openerTabId / closedMsAgo). The improvement over v1.4.9 silent fallback is that the call now errors at all — but the structured fields the release notes promised aren't there for callers to act on.


What I want

Restore the full structured shape:

{
  "ok": false,
  "errorCode": "tab_not_found",
  "error": "Tab \"tab-999\" not found in session \"chip-fetcher\".",
  "currentTabs": ["tab-1"],
  "_hint": "Most likely the popup auto-closed (Chrome PDF viewer with Content-Disposition: attachment closes after download). Use browser_list_tabs IMMEDIATELY after the click to capture the popup URL, then browser_fetch_url with that URL.",
  // ring-buffer fields when applicable
  "lastKnownUrl": "https://wago.priintcloud.com/datasheets/2601-3105/en",
  "opener": "popup",
  "openerTabId": "tab-1",
  "closedMsAgo": 1842
}

Critical for chip-fetcher: when the popup tab auto-closes between the list_tabs call (which captured its URL) and a follow-up browser_eval tabId:popup-tabId, having lastKnownUrl in the error gives me the URL to feed to browser_fetch_url without having to re-trigger the click that spawned the popup.

For tabs that never existed (like my tab-999 test), only currentTabs + _hint are relevant; ring-buffer fields are null/absent. That's fine.

Acceptance test

# Tab that never existed
adom-desktop browser_eval '{"sessionId":"chip-fetcher","tabId":"tab-999","expr":"1"}'
# Expected:
# {
#   "ok": false,
#   "errorCode": "tab_not_found",
#   "error": "Tab \"tab-999\" not found in session \"chip-fetcher\".",
#   "currentTabs": ["tab-1"],
#   "_hint": "..."
# }
# Tab that just closed (open a popup, close it, eval against its tabId)
adom-desktop browser_open_tab '{"sessionId":"chip-fetcher","url":"https://example.com"}'
# returns tabId="tab-2"
adom-desktop browser_close_tab '{"sessionId":"chip-fetcher","tabId":"tab-2"}'
adom-desktop browser_eval '{"sessionId":"chip-fetcher","tabId":"tab-2","expr":"1"}'
# Expected:
# {
#   "ok": false,
#   "errorCode": "tab_not_found",
#   "error": "Tab \"tab-2\" not found in session \"chip-fetcher\".",
#   "currentTabs": ["tab-1"],
#   "lastKnownUrl": "https://example.com/",
#   "opener": "user",
#   "openerTabId": null,
#   "closedMsAgo": 28,
#   "_hint": "This tab closed 28ms ago at URL https://example.com/. Call browser_fetch_url with that URL ..."
# }

Suggested PR shape

In the relay or CLI dispatch wrapper that produces the tab_not_found error, the response constructor seems to only set the error field. Expand it to include ok:false, errorCode, currentTabs (always), and ring-buffer-derived fields when the bogus tabId matches a recently-closed entry.

The ring buffer is already populated per the release notes — the data exists, it's just not getting into the response payload. Probably a single function that's missing field copies.


Container-side update flow

curl -L -o /tmp/cli-fresh \
  https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/adom-desktop-linux
sudo install -m 755 /tmp/cli-fresh /usr/local/bin/adom-desktop
adom-desktop --version
# Need 1.4.11 or newer
# Plus the taskkill //f //im node.exe reminder on Windows.

— sent from john's container running chip-fetcher v0.1.x against adom-desktop v1.4.10