Skip to content

fix(webui): fetch harness roster on connect, not first New Session open - #1236

Merged
edwin-zvs merged 1 commit into
mainfrom
issue-1098-harness-on-connect
Aug 7, 2026
Merged

fix(webui): fetch harness roster on connect, not first New Session open#1236
edwin-zvs merged 1 commit into
mainfrom
issue-1098-harness-on-connect

Conversation

@edwin-zvs

Copy link
Copy Markdown
Contributor

Fixes #1098.

Problem

The Playbook clip picker builds its harness rows and the harness ▸ category from state.harnesses, but that list was only populated inside openNewSessionDialog(). On a fresh page load the picker offered sessions only — @{harness:…} could not be inserted from the web UI at all until the New Session sheet had been opened once.

Change

harness.list is fleet state, so it now travels with the connect flow:

  • New shared refreshHarnesses() helper (next to refreshSessions) fetches harness.list into state.harnesses.
  • The websocket open handler calls it on every (re)connect — the roster can change across a daemon restart, which is exactly when reconnects happen.
  • openNewSessionDialog() uses the same helper: it still refreshes availability at open time and keeps its error surface, just through the shared path.

Acceptance criteria

  • Typing @ in a freshly loaded web UI offers harness clips and the harness ▸ category, with no prior visit to the New Session sheet — regression-tested.
  • The harness list survives a websocket reconnect — regression-tested (roster cleared, socket force-closed, reasserted after reconnect).
  • The New Session dialog keeps working from the shared state (no double fetch) — it now calls the shared helper.

Regression test

Added to web_smoke::web_client_loads_and_websocket_connects (real headless Chromium against a real daemon): polls state.harnesses after connect, asserts playbookClipRootRows("") contains category:harness and an @{harness:…} clip before any dialog interaction, then forces state.ws.close() and asserts the roster repopulates. Verified the new assertions fail against the pre-fix index.html (state.harnesses never populated from the connect flow) and pass with the fix.

The Playbook clip picker builds its harness rows and the 'harness >'
category from state.harnesses, but that list was only populated inside
openNewSessionDialog(). On a fresh page load the picker offered sessions
only, and @{harness:...} clips were uninsertable from the web UI even
though the empty-state help advertises them.

harness.list is fleet state: fetch it in the websocket open handler via
a shared refreshHarnesses() helper, so it is populated on first connect
and refreshed on every reconnect (the roster can change across a daemon
restart, which is exactly when reconnects happen). The New Session
dialog now uses the same helper, keeping its open-time availability
refresh and error surface.

Regression coverage in web_smoke: a freshly loaded page must offer the
harness category and @{harness:...} clips in playbookClipRootRows with
no prior New Session visit, and the roster must repopulate after a
forced websocket reconnect.

Closes #1098
@edwin-zvs
edwin-zvs merged commit 7b106ae into main Aug 7, 2026
1 check passed
@edwin-zvs
edwin-zvs deleted the issue-1098-harness-on-connect branch August 7, 2026 15:11
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.

web UI: playbook clip picker has no harness section until the New Session sheet has been opened once

1 participant