+
{workspaceId}
-
+
Sessions
{total > 0 && (
)}
+
+
+
- {workspaceId}
+
+ {workspaceId}
+
@@ -74,10 +113,10 @@ export function SessionList() {
/>
)}
- {!isLoading && sessions.length > 0 && (
+ {!isLoading && sorted.length > 0 && (
<>
- {sessions.map((session) => (
+ {sorted.map((session) => (
{session.id}
@@ -125,7 +164,7 @@ export function SessionList() {
)}
@@ -135,7 +174,7 @@ export function SessionList() {
{new Date(session.created_at).toLocaleString()}
@@ -147,7 +186,7 @@ export function SessionList() {
style={{
background: COLOR.accentDim,
border: `1px solid ${COLOR.accentBorderStrong}`,
- color: "rgba(148,163,184,0.6)",
+ color: COLOR.dimText,
}}
>
{(session.metadata as Record
).source}
diff --git a/src/components/settings/SettingsForm.tsx b/packages/web/src/components/settings/SettingsForm.tsx
similarity index 84%
rename from src/components/settings/SettingsForm.tsx
rename to packages/web/src/components/settings/SettingsForm.tsx
index e2ed7b7..8a74120 100644
--- a/src/components/settings/SettingsForm.tsx
+++ b/packages/web/src/components/settings/SettingsForm.tsx
@@ -1,19 +1,19 @@
-import { useState } from "react";
-import { motion, AnimatePresence } from "framer-motion";
-import { Wifi, WifiOff, Loader, CheckCircle, AlertCircle, Lock, LockOpen } from "lucide-react";
-import {
- configSchema,
- loadConfig,
- saveConfig,
- checkConnection,
- type Config,
- type HealthStatus,
-} from "@/lib/config";
import { Button } from "@/components/ui/button";
import { Input, Textarea } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Muted } from "@/components/ui/typography";
+import {
+ type Config,
+ type HealthStatus,
+ checkConnection,
+ configSchema,
+ loadConfig,
+ saveConfig,
+} from "@/lib/config";
import { COLOR } from "@/lib/constants";
+import { AnimatePresence, motion } from "framer-motion";
+import { AlertCircle, CheckCircle, Loader, Lock, LockOpen, Wifi, WifiOff } from "lucide-react";
+import { useState } from "react";
interface SettingsFormProps {
onSaved?: () => void;
@@ -81,14 +81,15 @@ export function SettingsForm({ onSaved }: SettingsFormProps) {
>
{/* Base URL */}
-
+
{ setBaseUrl(e.target.value); setHealth(null); }}
+ onChange={(e) => {
+ setBaseUrl(e.target.value);
+ setHealth(null);
+ }}
placeholder="http://localhost:8000"
className="flex-1 font-mono rounded-xl"
/>
@@ -100,7 +101,10 @@ export function SettingsForm({ onSaved }: SettingsFormProps) {
className="rounded-xl"
>
{checking ? (
-
+
) : (
@@ -110,11 +114,11 @@ export function SettingsForm({ onSaved }: SettingsFormProps) {
{errors.baseUrl && (
-
{errors.baseUrl}
+
+ {errors.baseUrl}
+
)}
-
- URL of your self-hosted Honcho instance
-
+
URL of your self-hosted Honcho instance
{/* Health status */}
@@ -141,12 +145,13 @@ export function SettingsForm({ onSaved }: SettingsFormProps) {
/>
)}
-
+
{statusConfig[health.status].label}
-
- {health.message}
-
+
{health.message}
@@ -155,14 +160,15 @@ export function SettingsForm({ onSaved }: SettingsFormProps) {
{/* Token */}
-
)}
{title}
- {description && (
-
{description}
- )}
+ {description &&
{description}}
{action &&
{action}
}
);
diff --git a/src/components/shared/ErrorAlert.tsx b/packages/web/src/components/shared/ErrorAlert.tsx
similarity index 52%
rename from src/components/shared/ErrorAlert.tsx
rename to packages/web/src/components/shared/ErrorAlert.tsx
index 9abf7a9..b503219 100644
--- a/src/components/shared/ErrorAlert.tsx
+++ b/packages/web/src/components/shared/ErrorAlert.tsx
@@ -1,3 +1,5 @@
+import { COLOR } from "@/lib/constants";
+
interface ErrorAlertProps {
error: Error | null;
message?: string;
@@ -9,14 +11,14 @@ export function ErrorAlert({ error, message }: ErrorAlertProps) {
-
+
{message ?? "An error occurred"}
-
+
{error.message}
diff --git a/src/components/shared/FormModal.tsx b/packages/web/src/components/shared/FormModal.tsx
similarity index 86%
rename from src/components/shared/FormModal.tsx
rename to packages/web/src/components/shared/FormModal.tsx
index cff820c..af6b429 100644
--- a/src/components/shared/FormModal.tsx
+++ b/packages/web/src/components/shared/FormModal.tsx
@@ -1,9 +1,4 @@
-import {
- Dialog,
- DialogContent,
- DialogHeader,
- DialogTitle,
-} from "@/components/ui/dialog";
+import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { cn } from "@/lib/utils";
interface FormModalProps {
diff --git a/src/components/shared/InlineEditor.tsx b/packages/web/src/components/shared/InlineEditor.tsx
similarity index 87%
rename from src/components/shared/InlineEditor.tsx
rename to packages/web/src/components/shared/InlineEditor.tsx
index 395546a..9f00ea0 100644
--- a/src/components/shared/InlineEditor.tsx
+++ b/packages/web/src/components/shared/InlineEditor.tsx
@@ -1,5 +1,5 @@
-import { useState, useRef, useEffect } from "react";
-import { Pencil, Check, X } from "lucide-react";
+import { Check, Pencil, X } from "lucide-react";
+import { useEffect, useRef, useState } from "react";
interface InlineEditorProps {
value: string;
@@ -41,6 +41,7 @@ export function InlineEditor({
if (!editing) {
return (
);
diff --git a/packages/web/src/components/shared/MarkdownRenderer.tsx b/packages/web/src/components/shared/MarkdownRenderer.tsx
new file mode 100644
index 0000000..9654740
--- /dev/null
+++ b/packages/web/src/components/shared/MarkdownRenderer.tsx
@@ -0,0 +1,549 @@
+import { TimestampChip } from "@/components/shared/TimestampChip";
+import { COLOR } from "@/lib/constants";
+import { Link } from "@tanstack/react-router";
+import { DateTime } from "luxon";
+import ReactMarkdown, { type Components } from "react-markdown";
+import remarkGfm from "remark-gfm";
+
+// ─── Types ────────────────────────────────────────────────────────────────────
+
+type Confidence = "high" | "medium" | "low";
+
+interface PatternBlock {
+ confidence: Confidence;
+ description: string;
+ type: string;
+ sources: string[];
+}
+
+interface ContradictionBlock {
+ description: string;
+ conflictingStatements: string[];
+}
+
+interface ContentSection {
+ heading: string | null;
+ rawBody: string;
+}
+
+// ─── Constants ────────────────────────────────────────────────────────────────
+
+const TIMESTAMP_LINE_RE = /^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]\s*(.*)/s;
+
+const CONFIDENCE_STYLE: Record