wsb-daemon 0.275.7622

wsb's daemon: the workbench, the GitHub mirror's schedule and peer continuity, for every workspace on the machine
<script lang="ts">
  // What one tab shows.
  //
  // The group's body scrolls and lays its content out as a column (the kit's
  // application surface), so each view is placed as it is.
  //
  // A worktree's document is mounted in that worktree's scope, so it reads its
  // own worktree's state whichever worktree is the context, and keyed by it, so
  // nothing one worktree's view held leaks into another's. The workshop's pages
  // are the machine's and need no scope.
  //
  // The transcript and the issue views read the one session and the one issue
  // being read, so they are shown in the group the reader is in; a group
  // holding another one in front offers to read it there.
  import { Button, EmptyState } from "@wsb/uikit/components";
  import { keyed } from "@wsb/uikit/handles";
  import { worktreeOf } from "../../api/types/workbench.js";
  import { workbench, type EditorTab } from "../../stores/workbench.svelte.js";
  import WorktreeScope from "./WorktreeScope.svelte";
  import SessionTab from "./SessionTab.svelte";
  import FileEditor from "../content/FileEditor.svelte";
  import DiffViewer from "../content/DiffViewer.svelte";
  import NodeInfoEditor from "../content/NodeInfoEditor.svelte";
  import ExternalSourceViewer from "../content/ExternalSourceViewer.svelte";
  import WebviewPanel from "../content/WebviewPanel.svelte";
  import CatalogueDiagnostics from "../content/CatalogueDiagnostics.svelte";
  import SessionStatistics from "../content/SessionStatistics.svelte";
  import RefactorReview from "../content/RefactorReview.svelte";
  import OpOutputView from "../opoutput/OpOutputView.svelte";
  import OverviewPage from "../overview/OverviewPage.svelte";
  import PlanEditor from "../plans/PlanEditor.svelte";
  import GistEditorTab from "../gists/GistEditorTab.svelte";
  import IssueDetail from "../issues/IssueDetail.svelte";
  import ExtensionsPage from "../extensions/ExtensionsPage.svelte";
  import WsbSettingsPage from "../settings/WsbSettingsPage.svelte";
  import MachineHome from "../levels/MachineHome.svelte";
  import BoardPage from "../levels/BoardPage.svelte";
  import ProjectsPage from "../levels/ProjectsPage.svelte";
  import ProjectView from "../levels/ProjectView.svelte";

  interface Props {
    group: string;
    tab: EditorTab;
  }

  let { group, tab }: Props = $props();

  const input = $derived(tab.input);
  const worktree = $derived(worktreeOf(input));
  const inFront = $derived(workbench.bench.focused === group);
</script>

{#snippet elsewhere(what: string)}
  {#snippet readHere()}
    <Button handle={keyed("editor.read-here", tab.key)} label="Read it here" onpress={() => workbench.bench.activate(group, tab.key)} />
  {/snippet}
  <EmptyState icon={tab.icon} title={tab.label} detail={`The ${what} being read is shown in the group you are in.`} action={readHere} />
{/snippet}

{#if worktree !== null}
  {#key worktree}
    <WorktreeScope {worktree}>
      {#if input.kind === "overview"}
        <OverviewPage />
      {:else if input.kind === "file"}
        <FileEditor path={input.path} line={input.line} column={input.column} />
      {:else if input.kind === "diff"}
        <DiffViewer path={input.path} repoPath={input.repoPath} />
      {:else if input.kind === "node-info"}
        <NodeInfoEditor path={input.path} />
      {:else if input.kind === "external"}
        <ExternalSourceViewer worktree={input.worktree} token={input.token} name={input.name} line={input.line} column={input.column} />
      {:else if input.kind === "webview"}
        <WebviewPanel title={tab.label} html={input.html} messages={input.messages} />
      {:else if input.kind === "catalogue-diagnostics"}
        <CatalogueDiagnostics />
      {:else if input.kind === "op-output"}
        <OpOutputView opId={input.opId} title={input.title} />
      {:else if input.kind === "refactor"}
        <RefactorReview tabKey={tab.key} planId={input.planId} root={input.root} />
      {:else if input.kind === "session"}
        {#if inFront}<SessionTab sessionId={input.sessionId} />{:else}{@render elsewhere("transcript")}{/if}
      {/if}
    </WorktreeScope>
  {/key}
{:else if input.kind === "session"}
  {#if inFront}<SessionTab sessionId={input.sessionId} />{:else}{@render elsewhere("transcript")}{/if}
{:else if input.kind === "boards"}
  <MachineHome />
{:else if input.kind === "board"}
  <BoardPage owner={input.owner} number={input.number} />
{:else if input.kind === "projects"}
  <ProjectsPage />
{:else if input.kind === "project"}
  <ProjectView project={input.project} />
{:else if input.kind === "gist"}
  <GistEditorTab mode="edit" gistId={input.gistId} />
{:else if input.kind === "gist-new"}
  <GistEditorTab mode="create" />
{:else if input.kind === "issue"}
  {#if inFront}<IssueDetail />{:else}{@render elsewhere("issue")}{/if}
{:else if input.kind === "extension"}
  <ExtensionsPage {input} />
{:else if input.kind === "settings"}
  <WsbSettingsPage />
{:else if input.kind === "plan"}
  <PlanEditor name={input.name} />
{:else if input.kind === "session-statistics"}
  <SessionStatistics />
{/if}