wsb-daemon 0.275.7622

wsb's daemon: the workbench, the GitHub mirror's schedule and peer continuity, for every workspace on the machine
<!--
  The latest agent sessions on this machine, or in one project's worktrees.

  A machine read, filtered by where the sessions ran. Each opens in the
  workbench of the worktree it ran in; a session that ran outside every
  project has no worktree to open it in, and says so instead of linking.
-->
<script lang="ts">
  import { listSessions, type SessionPlaceFilter } from "../../api/client.js";
  import type { Session } from "../../api/types.js";
  import { formatRelativeTime } from "../../utils/format.js";
  import { placeLabel } from "../../utils/places.js";
  import { workbench } from "../../stores/workbench.svelte.js";

  interface Props {
    /** Only sessions that ran here; every session on the machine when absent. */
    place?: SessionPlaceFilter;
    limit?: number;
  }

  let { place, limit = 20 }: Props = $props();

  let list = $state<Session[]>([]);
  let total = $state(0);
  let loading = $state(true);
  let error = $state<string | null>(null);

  async function load(filter: SessionPlaceFilter | undefined, count: number) {
    loading = true;
    try {
      const page = await listSessions({ place: filter, limit: count });
      list = page.sessions;
      total = page.total;
      error = null;
    } catch (failure) {
      error = failure instanceof Error ? failure.message : String(failure);
    } finally {
      loading = false;
    }
  }

  $effect(() => {
    void load(place, limit);
  });

  function title(session: Session): string {
    return session.display_name?.trim() || session.first_message?.trim() || session.id;
  }
</script>

<div class="placed-sessions">
  <div class="placed-sessions-head">
    <span class="subtle">
      {#if loading && list.length === 0}
        Reading sessions…
      {:else}
        Latest {list.length} of {total}
      {/if}
    </span>
    <button class="quiet" disabled={loading} onclick={() => void load(place, limit)}>Refresh</button>
  </div>
  {#if error}
    <p class="placed-sessions-error" role="alert">{error}</p>
  {/if}
  {#if !loading && list.length === 0 && !error}
    <p class="empty">No sessions{place ? ` ran in ${place.project}` : ""} yet.</p>
  {/if}
  <ul>
    {#each list as session (session.id)}
      <li>
        <!-- Opened in the worktree it ran in, when it ran in one. -->
        <button class="session-link" onclick={() => workbench.openSession(session, false)}>
          {title(session)}
        </button>
        <span class="subtle session-place">{placeLabel(session)}</span>
        <span class="subtle session-when">{formatRelativeTime(session.ended_at ?? session.started_at)}</span>
      </li>
    {/each}
  </ul>
</div>

<style>
  .placed-sessions-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--wb-spacing-6);
    font-size: var(--wb-font-size-12);
  }

  .placed-sessions-error {
    color: var(--wb-error);
    font-size: var(--wb-font-size-12);
  }

  ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  li {
    display: flex;
    align-items: baseline;
    gap: var(--wb-spacing-10);
    padding: var(--wb-spacing-4) 0;
    border-bottom: 1px solid var(--vscode-panel-border);
    font-size: var(--wb-font-size-12);
    min-width: 0;
  }

  .session-link {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
  }

  .session-link {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--vscode-textLink-foreground);
    font: inherit;
  }

  .session-link:hover {
    text-decoration: underline;
  }

  .session-place {
    flex-shrink: 0;
    font-family: var(--vscode-editor-font-family, monospace);
    font-size: var(--wb-font-size-11);
  }

  .session-when {
    flex-shrink: 0;
    font-size: var(--wb-font-size-11);
  }
</style>