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">
  import MarkdownPreview from "../content/MarkdownPreview.svelte";
  import { plans } from "../../stores/plans.svelte.js";

  let content = $state<string | null>(null);
  let error = $state<string | null>(null);

  interface Props {
    name: string;
  }

  let { name: planName }: Props = $props();

  let planLabel = $derived(plans.labelFor(planName));

  let planEntry = $derived(plans.plans.find((p) => p.name === planName) ?? null);

  function formatDate(unixSecs: number): string {
    return new Date(unixSecs * 1000).toLocaleDateString(undefined, {
      month: "long",
      day: "numeric",
      year: "numeric",
    });
  }

  async function load(name: string) {
    content = null;
    error = null;
    try {
      content = await plans.getContent(name);
    } catch (e) {
      error = e instanceof Error ? e.message : String(e);
    }
  }

  $effect(() => {
    void load(planName);
  });
</script>

<div class="plan-editor">
  <div class="plan-header">
    <div class="plan-header-left">
      <span class="plan-name">{planLabel}</span>
      {#if planEntry}
        <span class="plan-meta">Created {formatDate(planEntry.created_at)}</span>
      {/if}
    </div>
  </div>

  <div class="plan-body">
    {#if error}
      <div class="plan-error">{error}</div>
    {:else if content === null}
      <div class="plan-loading">Loading…</div>
    {:else}
      <MarkdownPreview {content} />
    {/if}
  </div>
</div>

<style>
  .plan-editor {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
  }

  .plan-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--wb-spacing-10) var(--wb-spacing-20);
    border-bottom: 1px solid var(--vscode-panel-border);
    flex-shrink: 0;
    gap: var(--wb-spacing-12);
  }

  .plan-header-left {
    display: flex;
    align-items: baseline;
    gap: var(--wb-spacing-12);
    min-width: 0;
  }

  .plan-name {
    font-size: var(--wb-font-size-13);
    font-weight: 600;
    color: var(--vscode-editor-foreground);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .plan-meta {
    font-size: var(--wb-font-size-11);
    color: var(--vscode-disabledForeground);
    white-space: nowrap;
  }

  .plan-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .plan-loading,
  .plan-error {
    padding: var(--wb-spacing-24) var(--wb-spacing-40);
    font-size: var(--wb-font-size-13);
    color: var(--vscode-disabledForeground);
  }

  .plan-error {
    color: var(--vscode-errorForeground);
  }
</style>