SPB Git

spb/khaelor Public

KHAELOR — a terminal-native autonomous engineering agent powered by Anthropic.

TypeScript 82.9% HTML 14.9% CSS 1.1% JavaScript 0.7%
2.3 KB · 69 lines typescript
Raw Blame History
1/**2 * KHAELOR3 * File: src/tui/components/verify-strip.ts4 * Description: The verify strip — live check progress that contracts to `✓ verified 4.2s` on success (TUI v2 §5.4).5 *6 * Author: Simon-Pierre Boucher7 * Contact: contact@spboucher.ai8 */910import { truncateAnsi } from "../renderer/ansi.js";11import type { Theme } from "../theme.js";1213export interface VerifyCheckState {14  check: string;15  state: "running" | "ok" | "failed";16  durationMs?: number;17  /** First error lines, shown inline on failure. */18  errorHead?: string[];19}2021/**22 * Live strip while checks run:  `⟳ verify   typecheck ✓ 1.2s · tests ⠧ · lint ✓`23 * All-passed contraction:       `✓ verified 4.2s`24 * Failure keeps the failing check pinned with its first error lines.25 */26export function renderVerifyStrip(27  checks: readonly VerifyCheckState[],28  width: number,29  theme: Theme,30): string[] {31  if (checks.length === 0) return [];32  const allDone = checks.every((check) => check.state !== "running");33  const allOk = allDone && checks.every((check) => check.state === "ok");3435  if (allOk) {36    const totalMs = Math.max(...checks.map((check) => check.durationMs ?? 0));37    return [38      truncateAnsi(39        ` ${theme.paint("success", "✓")} ${theme.paint("success", `verified ${(totalMs / 1000).toFixed(1)}s`)}` +40          ` ${theme.paint("dim", checks.map((check) => check.check).join(" · "))}`,41        width,42      ),43    ];44  }4546  const parts = checks.map((check) => {47    if (check.state === "running") return `${check.check} ${theme.paint("teal", "⠧")}`;48    if (check.state === "ok") {49      const secs = check.durationMs !== undefined ? ` ${(check.durationMs / 1000).toFixed(1)}s` : "";50      return `${check.check} ${theme.paint("success", "✓")}${theme.paint("dim", secs)}`;51    }52    return theme.paint("error", `${check.check} ✗`);53  });54  const lines = [55    truncateAnsi(56      ` ${theme.paint("accent", "⟳")} ${theme.paint("bold", "verify")}   ${parts.join(theme.paint("dim", " · "))}`,57      width,58    ),59  ];60  for (const check of checks) {61    if (check.state === "failed" && check.errorHead !== undefined) {62      for (const errorLine of check.errorHead.slice(0, 3)) {63        lines.push(truncateAnsi(`   ${theme.paint("dim", errorLine)}`, width));64      }65    }66  }67  return lines;68}69