SPB Git

spb/worthdoing Public

Autonomous investigation agent that discovers, challenges, and ranks things genuinely worth doing — Claude + Firecrawl, Next.js 16, PostgreSQL

TypeScript 91.5% SQL 5.8% CSS 2.2%
2.0 KB · 53 lines tsx
Raw Blame History
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: src/components/wd/HypothesisPanel.tsx6 * Description: Hypotheses panel — live confidence bars that strengthen/weaken with real events.7 */8"use client";910import { cn } from "@/lib/utils";11import type { UiHypothesis } from "@/lib/ui/api";12import { HypothesisBadge } from "./badges";13import { ConfidenceBar } from "./ConfidenceBar";1415export function HypothesisPanel({ hypotheses }: { hypotheses: UiHypothesis[] }) {16  if (hypotheses.length === 0) {17    return <p className="py-6 text-center font-mono text-xs text-ink-soft">no hypotheses formed yet</p>;18  }19  return (20    <ul className="space-y-4">21      {hypotheses.map((h) => (22        <li key={h.id} className={cn("wd-enter", h.status === "rejected" && "opacity-60")}>23          <div className="flex items-start justify-between gap-2">24            <p className={cn("text-[13px] font-medium leading-snug text-ink", h.status === "rejected" && "line-through decoration-rust/50")}>25              {h.title}26            </p>27            <HypothesisBadge status={h.status} />28          </div>29          <p className="mt-1 line-clamp-2 text-xs leading-relaxed text-ink-soft">{h.statement}</p>30          <div className="mt-2 flex items-center gap-2">31            <ConfidenceBar32              value={h.confidence}33              tone={h.status === "rejected" ? "rust" : "auto"}34              className="flex-1"35            />36            <span className="w-9 text-right font-mono text-[11px] text-ink-soft">37              {Math.round(h.confidence * 100)}%38            </span>39          </div>40          <div className="mt-1 flex items-center gap-2 font-mono text-[10px] uppercase tracking-wider text-ink-soft/80">41            {h.adversarialChecked ? (42              <span className="text-verdict">skeptic-tested ✓</span>43            ) : h.status !== "rejected" ? (44              <span>awaiting skeptic</span>45            ) : null}46            {h.parentHypothesisId && <span>· branch</span>}47          </div>48        </li>49      ))}50    </ul>51  );52}53