Skip to content

(remote): show a live remote session before its first transcript exists - #279

Merged
devsuitup merged 1 commit into
mainfrom
feat/278-blank-remote-session
Sep 12, 2026
Merged

devsuitup merged 1 commit into
mainfrom
feat/278-blank-remote-session

Conversation

@devsuitup

Copy link
Copy Markdown
Owner

Closes #278. Measured 2026-09-12 on the host: a CLI launched in tmux writes its descriptor at once and its transcript only after the first prompt; the row was missing for 3 minutes and a manual refresh did not help. Since #272 the row is the only place to stop a remote process.

What

  • remote-transport.js listFiles(): each live descriptor (ALIVE filter unchanged) is tagged descriptorOnly by cross-checking the transcript ids from the same ssh call — no extra round trip.
  • remote-index.js getPlaceholderSessions(alias): a session-shaped placeholder for each descriptor-only descriptor with a cwdsessionId = the descriptor's id, folder = encodeProjectPath(cwd), summary = cwd basename, status/statusUpdatedAt, remoteAlias, remoteDescriptorSeen: true, placeholder: true; computed on demand, nothing persisted or mirrored. findSessionAlias(sessionId) for sessions without a cache row.
  • main.js: mergePlaceholderSessions(projects) before annotateRemoteAttachable(), so the placeholder gets the same status / attachability treatment; open-terminal's remote branch resolves the alias from the index when getCachedFolder has no row (it used to fall through to a local spawn).
  • sidebar.js: no "View messages" control on a placeholder row; stop and attach work as on any live remote row.
  • Replacement: once the transcript is scanned the descriptor stops being descriptor-only and the real row, same sessionId, is what the sidebar renders — no swap code. The pid:<n> fallback id is unreachable with today's descriptor validation; stated in the doc.
  • Docs: session-cache.md (descriptor-only sessions), session-state.md (placeholder rows).

Proof

  • Transport: live descriptor-only kept and tagged, dead dropped. Index: placeholder synthesized; replaced in place when the transcript appears (one session, same id). DOM: placeholder row has .is-alive, the stop control, status text, no transcript button.
  • Mutations: dropping the buildPlaceholderSession push → synthesis and replacement tests red; removing the !session.placeholder guard → DOM test red. Both reverted.
  • task check: 1318 + 119 pass, 0 fail, pre-existing skips.

Not covered by a direct test: open-terminal's alias fallback branch (handler not source-extracted in tests; findSessionAlias unit-tested). Not verified on the wire.

Closes #278. The inventory tags each live descriptor with whether a
transcript matches it, in the same ssh call; the index synthesizes a
placeholder row for descriptor-only ones (project from cwd, same session id,
status and age, attachable and stoppable, no transcript affordance). Once the
transcript is scanned the descriptor is no longer descriptor-only and the
real row takes over under the same id. open-terminal resolves the host alias
from the index when the session has no cache row yet.
@devsuitup
devsuitup merged commit da98a3a into main Sep 12, 2026
14 of 15 checks passed
@devsuitup
devsuitup deleted the feat/278-blank-remote-session branch September 12, 2026 21:50
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.

(remote): a live remote session with no transcript yet is invisible and cannot be stopped

1 participant