Skip to content

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

Description

@edwin-zvs

The Playbook clip picker builds its harness rows from state.harnesses:

function playbookHarnessCandidates() {
  return state.harnesses.map((h) => {  clip: `@{harness:${name}}`  });
}
function playbookClipRootRows(query) {
  
  const harnessCount = state.harnesses.length;
  if (harnessCount) cats.push({ type: "category", group: "harness", count: harnessCount });
  
}

(crates/daemon/assets/index.html ~lines 8873–8908 @ ad47152)

But state.harnesses is only ever populated inside the New Session dialog:

async function openNewSessionDialog() {
  
  harnesses = await rpc("harness.list", null);
  state.harnesses = Array.isArray(harnesses) ? harnesses : [];

(index.html ~line 15255)

On a fresh page load it is [], so the picker shows sessions only: no harness rows in the relevance section, and the harness ▸ category row is suppressed entirely — which also makes the harness submenu unreachable. @{harness:…} cannot be inserted from the web UI at all, even though the empty-state help right above the editor advertises it ("@{harness:name} delegates").

Repro

  1. Load the web UI fresh, open a session's Playbook.
  2. Type @.

Observed — root rows are sessions plus one category:

["clip","clip","separator","category:session"]
state.harnesses.length === 0
  1. Open + new session, then cancel it. Type @ again:
["clip","clip","clip","clip","clip","separator","category:session","category:harness"]
state.harnesses → ["agy","claude","codex","grok","hermes","kimi","opencode","pi","shell","smith"]

The TUI's picker shows both categories unconditionally (session (3) ▸, harness (10) ▸).

Expected

harness.list is fleet state, not New-Session-dialog state. Fetch it on connect (alongside the session list) and refresh it on reconnect, so any consumer — the clip picker today, others later — sees it.

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.
  • The harness list survives a websocket reconnect.
  • The New Session dialog keeps working from the shared state (no double fetch required).

Found during a hands-on UX audit of the Playbook in the TUI and web UI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions