"use client";
import React, { useState, useEffect, useRef } from "react";
import {
Activity,
Terminal,
User,
Cpu,
ShieldAlert,
CheckCircle,
XCircle,
Database,
FileText,
Sparkles,
Send,
RefreshCw,
Play,
GitPullRequest,
Layers,
Settings,
AlertCircle,
Trash2,
HeartPulse,
LogOut,
Maximize2,
CloudSun,
Wind,
Droplets,
Thermometer,
Compass
} from "lucide-react";
export default function Page() {
const [activeTab, setActiveTab] = useState("dashboard");
// Claw Chat State
const [messages, setMessages] = useState([
{
role: "assistant",
content: "Hello! I am Claw, your local agent. Try:\n• `weather` — live weather for Mars, PA\n• `whatsapp me: message` — send now to your phone\n• `remind me at 3pm: call doctor` — schedule for later\n• `remind me tomorrow at 6am: gym` — future reminders\n• Or give me a list with times and I'll schedule them all!",
timestamp: "Just now"
}
]);
const [inputValue, setInputValue] = useState("");
const [isClawTyping, setIsClawTyping] = useState(false);
const [clawTerminalLogs, setClawTerminalLogs] = useState([]);
const [weatherCard, setWeatherCard] = useState(null);
const [weatherSending, setWeatherSending] = useState(false);
const [weatherSent, setWeatherSent] = useState(false);
const [scheduledReminders, setScheduledReminders] = useState([]);
// OpsAgent State
const [pendingApprovals, setPendingApprovals] = useState([
{
id: "ops-req-102",
targetType: "proxmox",
targetId: "102",
action: "clean_disk",
details: "LXC container root filesystem is at 94% disk usage. Recommending apt cache clean and temporary file removal.",
timestamp: "5 mins ago",
status: "pending"
},
{
id: "ops-req-201",
targetType: "kubernetes",
targetId: "curio-app-xyz",
action: "restart_pod",
details: "Pod curio-app-xyz is in CrashLoopBackOff state. Logs indicate: 'Database connection failed: Connection refused by 10.96.20.10:5432'. Recommending pod deletion to trigger k8s reschedule.",
timestamp: "10 mins ago",
status: "pending"
}
]);
const [opsLogs, setOpsLogs] = useState([
"2026-05-29 01:10:00 [OpsAgent] Initialized diagnostic run on K8s cluster...",
"2026-05-29 01:10:15 [OpsAgent] Found Pod 'curio-app-xyz' in CrashLoopBackOff. Emitting warning.",
"2026-05-29 01:12:02 [OpsAgent] Proxmox VMID 102 root usage checked: 94%. Action required."
]);
// Curio HMS State
const [dictationText, setDictationText] = useState(
"Patient is a 45-year-old male presenting with severe, crushing chest pain radiating to his left arm. He has a past medical history of hypertension. Admitting to Cardiac ICU."
);
const [clinicalNote, setClinicalNote] = useState(null);
const [billingCodes, setBillingCodes] = useState([]);
const [isProcessingClinical, setIsProcessingClinical] = useState(false);
// Workflow logs state
const [workflows, setWorkflows] = useState([
{ id: "wf-bernard-001", name: "PRReviewWorkflow", agent: "Bernard", target: "pr-401", status: "completed", result: "Approved with suggestions" },
{ id: "wf-gumbo-002", name: "GumboSummarizeWorkflow", agent: "Gumbo", target: "api-spec.md", status: "completed", result: "Summary persisted in PG" },
{ id: "wf-ops-003", name: "OpsRemediateWorkflow", agent: "OpsAgent", target: "VMID 102", status: "running", result: "Awaiting approval signal" }
]);
// Trips State
const [tripsList, setTripsList] = useState([]);
const [selectedTripId, setSelectedTripId] = useState(null);
const [tripEditorJson, setTripEditorJson] = useState("");
const [isSavingTrip, setIsSavingTrip] = useState(false);
const [isTestingTrip, setIsTestingTrip] = useState(false);
const messagesEndRef = useRef(null);
const terminalEndRef = useRef(null);
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages, isClawTyping]);
useEffect(() => {
terminalEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [clawTerminalLogs]);
useEffect(() => {
if (activeTab === "trips") {
fetch('/api/trips').then(res => res.json()).then(data => {
if(Array.isArray(data)) setTripsList(data);
}).catch(() => {});
}
}, [activeTab]);
// Simulated Claw response logic
const handleSendMessage = async (e) => {
e.preventDefault();
if (!inputValue.trim()) return;
const userText = inputValue;
setMessages(prev => [...prev, { role: "user", content: userText, timestamp: "Just now" }]);
setInputValue("");
setIsClawTyping(true);
setWeatherCard(null);
setWeatherSent(false);
setClawTerminalLogs(prev => [...prev, `[Claw] Received instruction: "${userText}"`]);
let responseText = "";
let logs = [];
const cleanInput = userText.toLowerCase();
// ── WhatsApp Send Command ────────────────────────────────────────────────
// Matches: "whatsapp me: ...", "send to whatsapp ...", "message me ...",
// "text me ...", "wa me ...", "send 'X' to my whatsapp"
const waIntent = /(?:whatsapp\s+me|message\s+me|text\s+me|send\s+(?:to\s+)?(?:my\s+)?whatsapp|wa\s+me|remind\s+me\s+via\s+whatsapp)[:\s]+(.+)/i;
const waMatch = userText.match(waIntent);
if (waMatch) {
const waMsg = waMatch[1].replace(/^["'`]|["'`]$/g, '').trim(); // strip surrounding quotes
setClawTerminalLogs(prev => [...prev,
`[Claw] WhatsApp send detected. Message: "${waMsg}"`,
`[Claw] Calling /api/send-whatsapp (personalOnly) ...`
]);
try {
const res = await fetch('/api/send-whatsapp', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: `📌 *Claw Reminder*\n\n${waMsg}`, personalOnly: true }),
});
const data = await res.json();
if (data.success) {
setClawTerminalLogs(prev => [...prev, `[Claw] ✅ Delivered to +14085505485. MsgID: ${data.messageId}`]);
responseText = `✅ Done! I've sent that to your WhatsApp (+14085505485):\n\n> "${waMsg}"\n\nYou should see it arrive shortly.`;
} else {
throw new Error(data.error || 'Gateway error');
}
} catch (err) {
setClawTerminalLogs(prev => [...prev, `[Claw] ❌ WhatsApp send failed: ${err.message}`]);
responseText = `❌ Couldn't send to WhatsApp: ${err.message}. Make sure the gateway is running.`;
}
// ── Scheduled Reminder ─────────────────────────────────────────────────────
// Patterns: "remind me at X: msg", "schedule (whatsapp) at X: msg",
// "send to whatsapp at X: msg", multi-bullet lists
} else if (
/(?:remind\s+me|schedule\s+(?:a\s+)?(?:whatsapp\s+)?(?:reminder|message)?)\s+(?:at|on|for|in|tomorrow|monday|tuesday|wednesday|thursday|friday|saturday|sunday)/i.test(userText) ||
/send\s+to\s+whatsapp\s+(?:at|in|tomorrow|on\s+)/i.test(userText) ||
// multi-bullet list: "schedule these:\n- msg at 3pm\n- msg2 at 6am"
(/(?:schedule|remind\s+me)/i.test(userText) && userText.includes('\n'))
) {
// Check for multi-item list (lines starting with - or •)
const lines = userText.split('\n').map(l => l.trim()).filter(Boolean);
const bulletLines = lines.filter(l => /^[-•*]\s+/.test(l) || (lines.length > 2 && l !== lines[0]));
const isBatch = bulletLines.length > 1;
if (isBatch) {
// Batch scheduling
const items = [];
const skipped = [];
for (const line of bulletLines) {
const clean = line.replace(/^[-•*]\s*/, '').trim();
// Try to split into message + time: "call doctor at 2pm" or "2pm: call doctor"
// Strategy: extract time, rest is the message
const sendAt = parseScheduleDateTime(clean);
if (!sendAt) { skipped.push(clean); continue; }
// Remove the time expression from the label
const label = clean.replace(/(at|by|on|for)?\s*\d{1,2}(?::\d{2})?\s*(am|pm)/gi, '').replace(/tomorrow|today|monday|tuesday|wednesday|thursday|friday|saturday|sunday/gi, '').replace(/in\s+\d+\s+(hour|hr|minute|min)s?/gi, '').trim().replace(/\s+/g, ' ');
const formatted = `⏰ *Claw Reminder*\n\n${label}\n\n_Scheduled for ${sendAt.toLocaleString('en-US', { timeZone: 'America/New_York', weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true })} ET_`;
items.push({ message: formatted, sendAt: sendAt.toISOString(), label });
}
if (items.length === 0) {
responseText = `❌ I couldn't parse any valid times from your list. Make sure each item includes a time like "at 3pm", "tomorrow at 9am", or "in 2 hours".`;
} else {
setClawTerminalLogs(prev => [...prev, `[Claw] Scheduling ${items.length} reminders...`]);
try {
const res = await fetch('/api/reminders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items }) });
const data = await res.json();
const lines2 = data.created?.map(c => `✅ "${c.label}" → ${formatReminderTime(c.sendAt)} ET`) || [];
if (skipped.length) lines2.push(...skipped.map(s => `⚠️ Skipped (no time): "${s}"`));
responseText = `📅 Scheduled ${data.created?.length || 0} reminder(s):\n\n${lines2.join('\n')}`;
// Refresh reminder panel
fetch('/api/reminders?status=pending').then(r => r.json()).then(d => { if (Array.isArray(d)) setScheduledReminders(d); });
setClawTerminalLogs(prev => [...prev, `[Claw] ✅ Batch scheduled: ${items.length} reminders`]);
} catch (err) {
responseText = `❌ Failed to schedule: ${err.message}`;
}
}
} else {
// Single reminder
// Parse message after colon: "remind me at 3pm: call doctor" → msg = "call doctor"
const colonSplit = userText.match(/[:\u2014]\s*(.+)$/s);
const msgText = colonSplit ? colonSplit[1].trim() : userText;
const sendAt = parseScheduleDateTime(userText);
if (!sendAt) {
responseText = `❌ I couldn't find a valid time in your message. Try: "remind me at 3pm: call doctor" or "remind me tomorrow at 9am: gym".`;
} else {
const etLabel = sendAt.toLocaleString('en-US', { timeZone: 'America/New_York', weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true });
const waMsg = `⏰ *Claw Reminder*\n\n${msgText}\n\n_Scheduled for ${etLabel} ET_`;
setClawTerminalLogs(prev => [...prev, `[Claw] Scheduling: "${msgText}" → ${sendAt.toISOString()}`]);
try {
const res = await fetch('/api/schedule-reminder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: waMsg, sendAt: sendAt.toISOString(), label: msgText }),
});
const data = await res.json();
if (data.success) {
responseText = `✅ Reminder scheduled!\n\n📌 **"${msgText}"**\n🕐 Delivers at **${etLabel} ET** to your WhatsApp (+14085505485)`;
fetch('/api/reminders?status=pending').then(r => r.json()).then(d => { if (Array.isArray(d)) setScheduledReminders(d); });
setClawTerminalLogs(prev => [...prev, `[Claw] ✅ Scheduled ID: ${data.id}`]);
} else {
throw new Error(data.error || 'Scheduling failed');
}
} catch (err) {
responseText = `❌ Couldn't schedule: ${err.message}`;
setClawTerminalLogs(prev => [...prev, `[Claw] ❌ ${err.message}`]);
}
}
}
} else if (cleanInput.includes("weather")) {
// Extract optional location override
const locMatch = userText.match(/(?:weather\s+(?:in|for|at)?\s*)(.+)/i);
const location = locMatch ? locMatch[1].trim() : '16046';
logs = [
`[Claw] Fetching live weather data for "${location}"...`,
"[Claw] Connecting to wttr.in weather service...",
];
setClawTerminalLogs(prev => [...prev, ...logs]);
try {
const res = await fetch(`/api/weather?location=${encodeURIComponent(location)}`);
const wx = await res.json();
if (wx.error) throw new Error(wx.error);
setWeatherCard(wx);
setClawTerminalLogs(prev => [...prev,
`[Claw] Got weather for ${wx.location}: ${wx.current.tempF}°F, ${wx.current.desc}`,
"[Claw] Rendering weather card. Use the button to push to WhatsApp."
]);
const emoji = getWeatherEmoji(wx.current.desc);
responseText = `${emoji} Here's the live weather for **${wx.location}**:\n\n🌡️ **${wx.current.tempF}°F** (feels like ${wx.current.feelsLikeF}°F) — ${wx.current.desc}\n💧 Humidity: ${wx.current.humidity}% | 💨 Wind: ${wx.current.windMph} mph ${wx.current.windDir}\n📊 Today: ${wx.today.minF}°F – ${wx.today.maxF}°F | 🌅 ${wx.today.sunrise} / 🌇 ${wx.today.sunset}\n\nI've generated the full report card below. Hit **Send to WhatsApp** to push it to your group!`;
} catch (err) {
responseText = `❌ Could not fetch weather: ${err.message}. Check your internet or try a city name like \`weather Toronto\`.`;
setClawTerminalLogs(prev => [...prev, `[Claw] Error: ${err.message}`]);
}
} else if (cleanInput.includes("pod") || cleanInput.includes("k8s") || cleanInput.includes("kubectl")) {
await new Promise(resolve => setTimeout(resolve, 1500));
logs = [
"Connecting to Kubernetes API server...",
"Executing: kubectl get pods -n default",
"Found 2 pods in namespace 'default':",
" - web-pod-xyz 0/1 CrashLoopBackOff 5 2h",
" - db-pod-abc 1/1 Running 0 5d",
"Fetching logs for 'web-pod-xyz'...",
" Error detected: Database connection refused by 10.96.20.10:5432"
];
responseText = "I've checked the Kubernetes pods. Pod `web-pod-xyz` is currently failing due to a database connection refusal. You can use the **OpsAgent** tab to approve a pod restart or scale the DB deployment.";
} else if (cleanInput.includes("proxmox") || cleanInput.includes("vmid") || cleanInput.includes("disk")) {
await new Promise(resolve => setTimeout(resolve, 1500));
logs = [
"Establishing SSH connection to Proxmox cluster host 192.168.8.225...",
"Running: pct status 102",
" status: running",
"Running: pct exec 102 -- df -h /",
" Filesystem Size Used Avail Use% Mounted on",
" /dev/loop0 20G 19G 0.2G 94% /",
"Disk usage critically high! Proposed action: clean_disk"
];
responseText = "Proxmox Container ID `102` is running out of disk space (94% used). I have created a pending action under the **OpsAgent Center** to perform automated cleanup. Would you like me to execute it?";
} else if (cleanInput.includes("hello") || cleanInput.includes("hi")) {
await new Promise(resolve => setTimeout(resolve, 800));
responseText = "Hi there! I am Claw, your local personal assistant. Try asking me to `check k8s pods`, `diagnose proxmox container 102`, or just type `weather` for a live report!";
} else {
await new Promise(resolve => setTimeout(resolve, 1200));
responseText = `I've analyzed your query: "${userText}". I recommend initiating an **OpsRemediateWorkflow** to check the status or scanning your configuration files. Let me know if you would like me to trigger that for you.`;
}
setClawTerminalLogs(prev => [...prev, ...logs, "[Claw] Response formulated successfully."]);
setMessages(prev => [...prev, { role: "assistant", content: responseText, timestamp: "Just now" }]);
setIsClawTyping(false);
};
// Weather emoji helper
const getWeatherEmoji = (desc) => {
const d = (desc || '').toLowerCase();
if (d.includes('sunny') || d.includes('clear')) return '☀️';
if (d.includes('partly cloudy')) return '⛅';
if (d.includes('cloud') || d.includes('overcast')) return '☁️';
if (d.includes('thunder') || d.includes('storm')) return '⛈️';
if (d.includes('rain') || d.includes('drizzle')) return '🌧️';
if (d.includes('snow') || d.includes('blizzard')) return '❄️';
if (d.includes('fog') || d.includes('mist')) return '🌫️';
return '🌤️';
};
// Send weather to WhatsApp
const handleSendWeatherToWhatsApp = async () => {
if (!weatherCard) return;
setWeatherSending(true);
const wx = weatherCard;
const emoji = getWeatherEmoji(wx.current.desc);
const msg = [
`${emoji} *Good Morning — Daily Weather Report*`,
`📍 *${wx.location}* (ZIP: ${wx.zip})`,
``,
`${emoji} ${wx.current.desc}`,
`🌡️ *Temp:* ${wx.current.tempF}°F (feels like ${wx.current.feelsLikeF}°F)`,
`💧 *Humidity:* ${wx.current.humidity}%`,
`💨 *Wind:* ${wx.current.windMph} mph ${wx.current.windDir}`,
`👁️ *Visibility:* ${wx.current.visibility} mi`,
`☀️ *UV Index:* ${wx.current.uvIndex}`,
``,
`📊 *Today:* ${wx.today.minF}°F – ${wx.today.maxF}°F`,
`🌅 Sunrise: ${wx.today.sunrise} 🌇 Sunset: ${wx.today.sunset}`,
wx.tomorrow ? `🔮 *Tomorrow:* ${wx.tomorrow.minF}°F – ${wx.tomorrow.maxF}°F ${getWeatherEmoji(wx.tomorrow.desc)} ${wx.tomorrow.desc}` : '',
``,
`_Agentic OS HQ • hq.applaude.net_ 🏠`,
].filter(Boolean).join('\n');
try {
const res = await fetch('/api/send-whatsapp', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: msg })
});
const data = await res.json();
if (data.success) {
setWeatherSent(true);
setMessages(prev => [...prev, { role: "assistant", content: "✅ Weather report sent to your WhatsApp group!", timestamp: "Just now" }]);
} else {
setMessages(prev => [...prev, { role: "assistant", content: `❌ Failed to send: ${data.error}`, timestamp: "Just now" }]);
}
} catch (err) {
setMessages(prev => [...prev, { role: "assistant", content: `❌ Error: ${err.message}`, timestamp: "Just now" }]);
} finally {
setWeatherSending(false);
}
};
// Poll scheduled reminders every 30s when on claw tab
useEffect(() => {
if (activeTab !== 'claw') return;
const fetchReminders = async () => {
try {
const res = await fetch('/api/reminders?status=pending');
if (res.ok) {
const data = await res.json();
if (Array.isArray(data)) setScheduledReminders(data);
}
} catch { /* reminder service may not be up yet */ }
};
fetchReminders();
const interval = setInterval(fetchReminders, 30000);
return () => clearInterval(interval);
}, [activeTab]);
// ── Natural-language date/time parser ────────────────────────────────────────
const parseScheduleDateTime = (text) => {
const t = text.toLowerCase();
const now = new Date();
// "in X hours/minutes"
const inMatch = t.match(/\bin\s+(\d+)\s+(hour|hr|minute|min)s?\b/);
if (inMatch) {
const n = parseInt(inMatch[1]);
const ms = inMatch[2].startsWith('h') ? n * 3600000 : n * 60000;
return new Date(now.getTime() + ms);
}
// Extract time component: "3pm", "6:30am", "14:00"
let hours = null, minutes = 0;
const ampm = t.match(/(\d{1,2})(?::(\d{2}))?\s*(am|pm)/);
const h24 = t.match(/(\d{2}):(\d{2})(?!\s*(am|pm))/);
if (ampm) {
hours = parseInt(ampm[1]);
minutes = ampm[2] ? parseInt(ampm[2]) : 0;
if (ampm[3] === 'pm' && hours !== 12) hours += 12;
if (ampm[3] === 'am' && hours === 12) hours = 0;
} else if (h24) {
hours = parseInt(h24[1]);
minutes = parseInt(h24[2]);
}
// Build date
let date = new Date(now);
let explicitDate = false;
if (t.includes('tomorrow')) {
date.setDate(date.getDate() + 1);
explicitDate = true;
} else {
const days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday'];
const dayIdx = days.findIndex(d => t.includes(d));
if (dayIdx !== -1) {
const diff = ((dayIdx - now.getDay()) + 7) % 7 || 7; // next occurrence
date.setDate(date.getDate() + diff);
explicitDate = true;
} else {
// Named month: "May 30", "June 1"
const months = ['january','february','march','april','may','june','july','august','september','october','november','december'];
const shortM = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
let mIdx = months.findIndex(m => t.includes(m));
if (mIdx === -1) mIdx = shortM.findIndex(m => t.match(new RegExp('\\b' + m + '\\b')));
if (mIdx !== -1) {
const dayNum = t.match(/(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\w*\s+(\d{1,2})/i);
if (dayNum) {
date.setMonth(mIdx, parseInt(dayNum[1]));
if (date < now) date.setFullYear(date.getFullYear() + 1);
explicitDate = true;
}
}
}
}
if (hours === null) return null; // no time found
date.setHours(hours, minutes, 0, 0);
// If the computed time is in the past and no explicit date was given, push to tomorrow
if (date <= now && !explicitDate) date.setDate(date.getDate() + 1);
return date;
};
// ── Format a Date nicely for display ─────────────────────────────────────────
const formatReminderTime = (isoStr) => {
const d = new Date(isoStr);
return d.toLocaleString('en-US', {
timeZone: 'America/New_York',
weekday: 'short', month: 'short', day: 'numeric',
hour: 'numeric', minute: '2-digit', hour12: true
});
};
// ── Cancel a reminder ─────────────────────────────────────────────────────────
const handleCancelReminder = async (id) => {
try {
const res = await fetch(`/api/reminders?id=${id}`, { method: 'DELETE' });
if (res.ok) setScheduledReminders(prev => prev.filter(r => r.id !== id));
} catch { /* silent */ }
};
const handleApprove = async (id, action, target) => {
setPendingApprovals(prev => prev.map(item => item.id === id ? { ...item, status: "approved" } : item));
setOpsLogs(prev => [...prev, `2026-05-29 01:14:10 [OpsAgent] RECEIVED APPROVAL SIGNAL for request ${id}`]);
// Simulate execution log
let execLogs = [
`[OpsAgent] Initiating execution of '${action}' on target '${target}'...`,
`[OpsAgent] Sending signal to Temporal workflow...`,
];
if (action === "clean_disk") {
execLogs.push(
"[OpsAgent] SSH into Proxmox node VMID 102...",
"[OpsAgent] running: apt-get clean && rm -rf /tmp/*",
"[OpsAgent] Disk space cleared. Root filesystem usage reduced from 94% to 71%."
);
} else {
execLogs.push(
`[OpsAgent] Running: kubectl delete pod ${target} -n default`,
`[OpsAgent] Pod deleted. K8s controller successfully scheduled a replica.`
);
}
// Delay log write to simulate real execution
for (const log of execLogs) {
await new Promise(resolve => setTimeout(resolve, 800));
setOpsLogs(prev => [...prev, log]);
}
setPendingApprovals(prev => prev.filter(item => item.id !== id));
setWorkflows(prev => prev.map(wf => wf.target === (action === "clean_disk" ? "VMID 102" : target) ? { ...wf, status: "completed", result: "Remediated successfully" } : wf));
};
const handleReject = (id) => {
setPendingApprovals(prev => prev.filter(item => item.id !== id));
setOpsLogs(prev => [...prev, `2026-05-29 01:14:30 [OpsAgent] Request ${id} REJECTED by operator. Action aborted.`]);
};
// Clinical note simulation
const handleProcessClinical = async () => {
setIsProcessingClinical(true);
setClinicalNote(null);
setBillingCodes([]);
await new Promise(resolve => setTimeout(resolve, 1500));
setClinicalNote({
subjective: "Patient is a 45-year-old male presenting with severe, crushing chest pain radiating to his left arm. He reports shortness of breath.",
objective: "Alert and oriented. Reports pain scale 8/10.",
assessment: "Acute Myocardial Infarction suspected.",
plan: "Order EKG, troponin levels. Administer Aspirin 324mg immediately. Admit to Cardiac ICU."
});
setBillingCodes([
{ code: "I21.9", desc: "Acute myocardial infarction, unspecified" },
{ code: "93000", desc: "Electrocardiogram, tracing and report" },
{ code: "99223", desc: "Initial hospital care, high level severity" }
]);
setIsProcessingClinical(false);
};
const handleSaveTrip = async () => {
try {
setIsSavingTrip(true);
let parsed = JSON.parse(tripEditorJson);
if (selectedTripId) {
await fetch(`/api/trips/${selectedTripId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(parsed)
});
} else {
await fetch('/api/trips', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(parsed)
});
}
const data = await fetch('/api/trips').then(r => r.json());
setTripsList(Array.isArray(data) ? data : []);
setSelectedTripId(null);
setTripEditorJson("");
} catch (e) {
alert("Invalid JSON or save failed: " + e.message);
} finally {
setIsSavingTrip(false);
}
};
const handleTestTrip = async (id) => {
setIsTestingTrip(true);
try {
const res = await fetch(`/api/trips/${id}/test`, { method: 'POST' });
const data = await res.json();
if (data.success) {
alert("Test briefing fired to WhatsApp successfully!");
} else {
alert("Test failed: " + JSON.stringify(data));
}
} catch (e) {
alert("Error triggering test: " + e.message);
} finally {
setIsTestingTrip(false);
}
};
return (
{/* Sidebar Navigation */}
{/* Main Content Area */}
{/* TAB 1: DASHBOARD HOME */}
{activeTab === "dashboard" && (
{/* Stat Cards */}
Total Active Agents
5 / 8
Active in namespace
Temporal Workflows
12 Active
98.8% success SLA
Diagnostic Logs
142 MB
Persisted in PostgreSQL
Action Approvals
{pendingApprovals.length} Awaiting
Require administrator override
{/* Agent Status Panel */}
Core Agent Ecosystem Status
{[
{ name: "Bernard", role: "GitOps Reviewer & Workflow Monitor", status: "Idle", desc: "Awaiting PR push events on Gitea hooks.", type: "system" },
{ name: "Gumbo", role: "Documentation Summarizer", status: "Active", desc: "Indexing recent technical wiki docs via MCP filesystem.", type: "assistant" },
{ name: "OpsAgent", role: "SRE Diagnostics & Self-Healing", status: "Pending approval", desc: "Awaiting administrator decision for remediation action.", type: "remediator" },
{ name: "Claw", role: "Local Assistant CLI (OpenClaw clone)", status: "Active", desc: "Awaiting operator prompt input.", type: "assistant" },
{ name: "Curio Billing/Triage", role: "HMS AI Assist", status: "Idle", desc: "Standing by for clinical intake recording inputs.", type: "clinical" },
].map((agent, i) => (
{agent.name}
{agent.role} — {agent.desc}
{agent.status}
))}
{/* Quick Trigger Block */}
Diagnostics & Ops Triggers
Knowledge Intake Trigger
)}
{/* TAB 2: CLAW PERSONAL ASSISTANT */}
{activeTab === "claw" && (
{/* Chat Panel */}
{/* Chat Header */}
Claw Personal Assistant
Runs locally. Accesses file tools & system terminal.
{/* Chat Messages */}
{messages.map((msg, i) => (
{msg.content}
{msg.timestamp}
))}
{isClawTyping && (
)}
{/* Weather Card */}
{weatherCard && (
{/* Card Header */}
{getWeatherEmoji(weatherCard.current.desc)}
📍 {weatherCard.location}
Live conditions • ZIP {weatherCard.zip}
{weatherCard.current.tempF}°F
feels like {weatherCard.current.feelsLikeF}°F
{/* Condition */}
{weatherCard.current.desc}
{/* Stats Grid */}
{[
{ icon: "💧", label: "Humidity", value: `${weatherCard.current.humidity}%` },
{ icon: "💨", label: "Wind", value: `${weatherCard.current.windMph} mph ${weatherCard.current.windDir}` },
{ icon: "☀️", label: `UV Index`, value: `${weatherCard.current.uvIndex}` },
{ icon: "👁️", label: "Visibility", value: `${weatherCard.current.visibility} mi` },
{ icon: "🔺", label: "High", value: `${weatherCard.today.maxF}°F` },
{ icon: "🔻", label: "Low", value: `${weatherCard.today.minF}°F` },
].map((stat, i) => (
{stat.icon}
{stat.value}
{stat.label}
))}
{/* Sunrise/Sunset & Tomorrow */}
🌅 {weatherCard.today.sunrise}
🌇 {weatherCard.today.sunset}
{weatherCard.tomorrow && (
{getWeatherEmoji(weatherCard.tomorrow.desc)} Tomorrow: {weatherCard.tomorrow.minF}–{weatherCard.tomorrow.maxF}°F
)}
{/* Send to WhatsApp CTA */}
)}
{/* Chat Input */}
{/* Claw Tool & Console Log Panel */}
{/* Terminal Console */}
Claw Tool Console
{clawTerminalLogs.length === 0 ? (
Console logs will stream here as Claw calls CLI and API tools...
) : (
clawTerminalLogs.map((log, i) => (
> {log}
))
)}
{/* Scheduled Reminders Panel */}
⏰
Scheduled Reminders
{scheduledReminders.length > 0 && (
{scheduledReminders.length}
)}
auto-refreshes
{scheduledReminders.length === 0 ? (
No reminders scheduled.
Try: "remind me at 3pm: call doctor"
) : (
scheduledReminders.map((r) => (
{r.label}
🕐 {formatReminderTime(r.sendAt)} ET
))
)}
)}
{/* TAB 3: OPSAGENT HUB */}
{activeTab === "ops" && (
{/* Left Column: Diagnostics and Approvals */}
{/* Pending Actions */}
Awaiting System Approvals (Approval Gate)
{pendingApprovals.length === 0 ? (
No approvals pending
All systems are running clean and within normal parameters.
) : (
{pendingApprovals.map((req) => (
{req.action.replace("_", " ")}
Target: {req.targetType.toUpperCase()} ({req.targetId})
{req.timestamp}
{req.details}
))}
)}
{/* Diagnostics Panel */}
OpsAgent Diagnostics Tools
Manually run automated checks across your container nodes.
K8s Diagnostic
Proxmox Auditor
{/* Right Column: Execution Live Terminal */}
OpsAgent Execution Terminal Logs
{opsLogs.map((log, i) => (
{log}
))}
)}
{/* TAB 4: CLINICAL WORKSPACE */}
{activeTab === "curio" && (
{/* Doctor Dictation Section */}
Clinical Scribe Workspace
Uses ClinicalIntakeWorkflow (Temporal Task Queue)
{/* Structuring Result Output */}
Structured Output (SOAP Note)
{clinicalNote ? (
SUBJECTIVE
{clinicalNote.subjective}
OBJECTIVE
{clinicalNote.objective}
ASSESSMENT
{clinicalNote.assessment}
Generated Billing Codes (ICD-10 / CPT)
| Code |
Description |
{billingCodes.map((bc, idx) => (
| {bc.code} |
{bc.desc} |
))}
) : (
No workflow submitted yet. Enter dictation and click submit.
)}
)}
{/* TAB 5: WORKFLOW MONITOR */}
{activeTab === "logs" && (
Durable Execution Logs
Temporal workflows audit records inside the local postgres cluster.
| Workflow ID |
Workflow Name |
Assigned Agent |
Target |
Status |
Result |
{workflows.map((wf) => (
| {wf.id} |
{wf.name} |
{wf.agent} |
{wf.target} |
{wf.status}
|
{wf.result} |
))}
)}
{/* TAB 6: TRIPS & CONFIG */}
{activeTab === "trips" && (
{/* Trip List Panel */}
Managed Trips
{tripsList.map(t => (
{
setSelectedTripId(t.id);
setTripEditorJson(JSON.stringify(t, null, 2));
}}
style={{ padding: "12px", border: `1px solid ${selectedTripId === t.id ? 'var(--accent-pink)' : 'var(--border-color)'}`, borderRadius: "8px", background: selectedTripId === t.id ? "rgba(236,72,153,0.05)" : "var(--bg-secondary)", cursor: "pointer" }}
>
{t.name}
⏰ {t.briefingTime} ET
{t.days?.length} Days
))}
{/* Editor Panel */}
{selectedTripId ? "Edit Trip Configuration" : "New Trip Configuration"}
{selectedTripId && (
)}
)}
);
}