// src/ts/index.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

// src/ts/App.tsx
import { useState as useState11, useEffect as useEffect9, useCallback as useCallback10, useRef as useRef6 } from "react";

// src/ts/api.ts
var BASE = "/api";
async function request(path, init) {
  const resp = await fetch(`${BASE}${path}`, {
    ...init,
    headers: {
      "Content-Type": "application/json",
      ...init?.headers ?? {}
    }
  });
  if (!resp.ok) {
    const body = await resp.json().catch(() => ({ error: resp.statusText }));
    throw new Error(body.error ?? `HTTP ${resp.status}`);
  }
  return resp.json();
}
async function listAgents(tenantId, status) {
  const params = new URLSearchParams();
  if (tenantId) params.set("tenant_id", tenantId);
  if (status) params.set("status", status);
  const qs = params.toString();
  return request(`/agents${qs ? `?${qs}` : ""}`);
}
async function getAgent(agentId) {
  return request(`/agents/${encodeURIComponent(agentId)}`);
}
async function launchAgent(profileId, opts) {
  return request("/agents", {
    method: "POST",
    body: JSON.stringify({ profile_id: profileId, ...opts })
  });
}
async function stopAgent(agentId) {
  return request(`/agents/${encodeURIComponent(agentId)}/stop`, {
    method: "POST"
  });
}
async function killAgent(agentId) {
  return request(`/agents/${encodeURIComponent(agentId)}/kill`, {
    method: "POST"
  });
}
async function restartAgent(agentId) {
  return request(`/agents/${encodeURIComponent(agentId)}/restart`, {
    method: "POST"
  });
}
async function sendMessageToAgent(agentId, body) {
  return request(`/agents/${encodeURIComponent(agentId)}/message`, {
    method: "POST",
    body: JSON.stringify({ body })
  });
}
async function listProfiles(tenantId) {
  const qs = tenantId ? `?tenant_id=${encodeURIComponent(tenantId)}` : "";
  return request(`/profiles${qs}`);
}
async function createProfile(profile) {
  return request("/profiles", {
    method: "POST",
    body: JSON.stringify(profile)
  });
}
async function getProfile(profileId) {
  return request(`/profiles/${encodeURIComponent(profileId)}`);
}
async function deleteProfile(profileId) {
  return request(`/profiles/${encodeURIComponent(profileId)}`, {
    method: "DELETE"
  });
}
async function updateProfile(profileId, updates) {
  return request(`/profiles/${encodeURIComponent(profileId)}`, {
    method: "PUT",
    body: JSON.stringify(updates)
  });
}
async function listPreconfiguredAgents() {
  const data = await request(
    "/agents/preconfigured"
  );
  return data.agents;
}
async function saveAgentToDisk(profile) {
  return request("/agents/preconfigured/save", {
    method: "POST",
    body: JSON.stringify(profile)
  });
}
async function generateAgentProfile(agentId) {
  return request(`/agents/${encodeURIComponent(agentId)}/generate-profile`, {
    method: "POST"
  });
}
async function fetchActivity(limit) {
  const qs = limit ? `?limit=${limit}` : "";
  return request(`/activity${qs}`);
}
async function queryAudit(tenantId, opts) {
  const params = new URLSearchParams({ tenant_id: tenantId });
  if (opts?.agent_id) params.set("agent_id", opts.agent_id);
  if (opts?.event_type) params.set("event_type", opts.event_type);
  if (opts?.limit) params.set("limit", String(opts.limit));
  if (opts?.offset) params.set("offset", String(opts.offset));
  return request(`/audit?${params}`);
}
async function queryMessages(channel, opts) {
  const params = new URLSearchParams({ channel });
  if (opts?.from_seq) params.set("from_seq", String(opts.from_seq));
  if (opts?.limit) params.set("limit", String(opts.limit));
  return request(`/messages?${params}`);
}
async function listChannels() {
  return request("/channels");
}
async function listCheckpoints(agentId) {
  return request(
    `/agents/${encodeURIComponent(agentId)}/checkpoints`
  );
}
async function replayMessage(sourceChannel, messageId, targetChannel) {
  return request(`/messages/replay`, {
    method: "POST",
    body: JSON.stringify({
      source_channel: sourceChannel,
      message_id: messageId,
      target_channel: targetChannel
    })
  });
}
async function fetchProviders() {
  const data = await request("/providers");
  return data.providers;
}

// src/ts/ws.ts
var LangleyWsClient = class {
  url;
  ws = null;
  subscriptions = /* @__PURE__ */ new Map();
  reconnectDelay = 1e3;
  maxReconnectDelay = 3e4;
  currentDelay = 1e3;
  shouldReconnect = true;
  reconnectTimer = null;
  onConnect;
  onDisconnect;
  onError;
  constructor(url) {
    const proto = window.location.protocol === "https:" ? "wss:" : "ws:";
    this.url = url ?? `${proto}//${window.location.host}/ws`;
  }
  connect() {
    this.shouldReconnect = true;
    this._connect();
  }
  _connect() {
    if (this.ws) return;
    try {
      this.ws = new WebSocket(this.url);
    } catch {
      this._scheduleReconnect();
      return;
    }
    this.ws.onopen = () => {
      this.currentDelay = this.reconnectDelay;
      this.onConnect?.();
      for (const channel of this.subscriptions.keys()) {
        this._sendFrame({ type: "subscribe", channel });
      }
    };
    this.ws.onmessage = (event) => {
      let frame;
      try {
        frame = JSON.parse(event.data);
      } catch {
        return;
      }
      this._handleFrame(frame);
    };
    this.ws.onclose = () => {
      this.ws = null;
      this.onDisconnect?.();
      this._scheduleReconnect();
    };
    this.ws.onerror = () => {
    };
  }
  disconnect() {
    this.shouldReconnect = false;
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }
  subscribe(channel, handler) {
    let handlers = this.subscriptions.get(channel);
    if (!handlers) {
      handlers = /* @__PURE__ */ new Set();
      this.subscriptions.set(channel, handlers);
      this._sendFrame({ type: "subscribe", channel });
    }
    handlers.add(handler);
    return () => {
      handlers.delete(handler);
      if (handlers.size === 0) {
        this.subscriptions.delete(channel);
        this._sendFrame({ type: "unsubscribe", channel });
      }
    };
  }
  send(channel, body, headers) {
    this._sendFrame({ type: "send", channel, body, headers });
  }
  ping() {
    this._sendFrame({ type: "ping" });
  }
  get connected() {
    return this.ws?.readyState === WebSocket.OPEN;
  }
  _sendFrame(frame) {
    if (this.ws?.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(frame));
    }
  }
  _handleFrame(frame) {
    if (frame.type === "message" && frame.channel && frame.data) {
      const handlers = this.subscriptions.get(frame.channel);
      if (handlers) {
        for (const h of handlers) {
          h(frame.data);
        }
      }
    } else if (frame.type === "error") {
      this.onError?.(frame.message ?? "Unknown error");
    }
  }
  _scheduleReconnect() {
    if (!this.shouldReconnect) return;
    this.reconnectTimer = setTimeout(() => {
      this.reconnectTimer = null;
      this._connect();
    }, this.currentDelay);
    this.currentDelay = Math.min(this.currentDelay * 2, this.maxReconnectDelay);
  }
};

// src/ts/components/StatusTab.tsx
import { useState as useState3, useCallback as useCallback2 } from "react";

// src/ts/components/SummaryCards.tsx
import { jsx, jsxs } from "react/jsx-runtime";
function SummaryCards({ agents }) {
  const counts = {
    total: agents.length,
    running: agents.filter((a) => a.status === "running").length,
    stopped: agents.filter((a) => a.status === "stopped").length,
    errored: agents.filter((a) => a.status === "errored").length,
    pending: agents.filter((a) => a.status === "pending").length
  };
  return /* @__PURE__ */ jsxs("div", { className: "langley-summary-cards", "data-testid": "summary-cards", children: [
    /* @__PURE__ */ jsxs("div", { className: "langley-card", "data-testid": "card-total", children: [
      /* @__PURE__ */ jsx("div", { className: "langley-card-value", children: counts.total }),
      /* @__PURE__ */ jsx("div", { className: "langley-card-label", children: "Total" })
    ] }),
    /* @__PURE__ */ jsxs("div", { className: "langley-card", "data-testid": "card-running", children: [
      /* @__PURE__ */ jsx("div", { className: "langley-card-value", children: counts.running }),
      /* @__PURE__ */ jsx("div", { className: "langley-card-label", children: "Running" })
    ] }),
    /* @__PURE__ */ jsxs("div", { className: "langley-card", "data-testid": "card-stopped", children: [
      /* @__PURE__ */ jsx("div", { className: "langley-card-value", children: counts.stopped }),
      /* @__PURE__ */ jsx("div", { className: "langley-card-label", children: "Stopped" })
    ] }),
    /* @__PURE__ */ jsxs("div", { className: "langley-card", "data-testid": "card-errored", children: [
      /* @__PURE__ */ jsx("div", { className: "langley-card-value", children: counts.errored }),
      /* @__PURE__ */ jsx("div", { className: "langley-card-label", children: "Errored" })
    ] }),
    /* @__PURE__ */ jsxs("div", { className: "langley-card", "data-testid": "card-pending", children: [
      /* @__PURE__ */ jsx("div", { className: "langley-card-value", children: counts.pending }),
      /* @__PURE__ */ jsx("div", { className: "langley-card-label", children: "Pending" })
    ] })
  ] });
}

// src/ts/components/AgentTable.tsx
import { useState, useCallback } from "react";

// src/ts/components/StatusBadge.tsx
import { jsx as jsx2 } from "react/jsx-runtime";
var colors = {
  running: "#22c55e",
  stopped: "#94a3b8",
  errored: "#ef4444",
  pending: "#f59e0b"
};
function StatusBadge({ status }) {
  return /* @__PURE__ */ jsx2(
    "span",
    {
      className: "langley-status-badge",
      style: { backgroundColor: colors[status] },
      "data-testid": `status-${status}`
    }
  );
}

// src/ts/components/AgentTable.tsx
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
function AgentTable({
  agents,
  onAction,
  onChat,
  onInspect,
  onBulkAction
}) {
  const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
  const toggleSelect = useCallback((id) => {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }, []);
  const toggleSelectAll = useCallback(() => {
    setSelected(
      (prev) => prev.size === agents.length ? /* @__PURE__ */ new Set() : new Set(agents.map((a) => a.id))
    );
  }, [agents]);
  const handleBulk = useCallback(
    (action) => {
      if (selected.size === 0) return;
      onBulkAction?.([...selected], action);
      setSelected(/* @__PURE__ */ new Set());
    },
    [selected, onBulkAction]
  );
  if (agents.length === 0) {
    return /* @__PURE__ */ jsx3("p", { className: "langley-empty", "data-testid": "no-agents", children: "No agents running." });
  }
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
    selected.size > 0 && onBulkAction && /* @__PURE__ */ jsxs2("div", { className: "langley-bulk-actions", "data-testid": "bulk-actions", children: [
      /* @__PURE__ */ jsxs2("span", { children: [
        selected.size,
        " selected"
      ] }),
      /* @__PURE__ */ jsx3("button", { className: "langley-btn", onClick: () => handleBulk("stop"), children: "Stop" }),
      /* @__PURE__ */ jsx3(
        "button",
        {
          className: "langley-btn langley-btn-danger",
          onClick: () => handleBulk("kill"),
          children: "Kill"
        }
      ),
      /* @__PURE__ */ jsx3("button", { className: "langley-btn", onClick: () => handleBulk("restart"), children: "Restart" })
    ] }),
    /* @__PURE__ */ jsxs2("table", { className: "langley-agent-table", "data-testid": "agent-table", children: [
      /* @__PURE__ */ jsx3("thead", { children: /* @__PURE__ */ jsxs2("tr", { children: [
        onBulkAction && /* @__PURE__ */ jsx3("th", { style: { width: 32 }, children: /* @__PURE__ */ jsx3(
          "input",
          {
            type: "checkbox",
            checked: selected.size === agents.length,
            onChange: toggleSelectAll,
            "data-testid": "select-all"
          }
        ) }),
        /* @__PURE__ */ jsx3("th", { children: "Status" }),
        /* @__PURE__ */ jsx3("th", { children: "Name" }),
        /* @__PURE__ */ jsx3("th", { children: "Profile" }),
        /* @__PURE__ */ jsx3("th", { children: "Uptime" }),
        /* @__PURE__ */ jsx3("th", { children: "Actions" })
      ] }) }),
      /* @__PURE__ */ jsx3("tbody", { children: agents.map((agent) => /* @__PURE__ */ jsxs2("tr", { "data-testid": `agent-row-${agent.id}`, children: [
        onBulkAction && /* @__PURE__ */ jsx3("td", { children: /* @__PURE__ */ jsx3(
          "input",
          {
            type: "checkbox",
            checked: selected.has(agent.id),
            onChange: () => toggleSelect(agent.id),
            "data-testid": `select-${agent.id}`
          }
        ) }),
        /* @__PURE__ */ jsx3("td", { children: /* @__PURE__ */ jsx3(StatusBadge, { status: agent.status }) }),
        /* @__PURE__ */ jsx3("td", { children: onInspect ? /* @__PURE__ */ jsx3(
          "button",
          {
            className: "langley-agent-name-link",
            onClick: () => onInspect(agent.id),
            "data-testid": `inspect-${agent.id}`,
            children: agent.name
          }
        ) : agent.name }),
        /* @__PURE__ */ jsx3("td", { children: agent.profile }),
        /* @__PURE__ */ jsxs2("td", { children: [
          Math.floor(agent.uptime_seconds),
          "s"
        ] }),
        /* @__PURE__ */ jsx3("td", { children: agent.status === "running" && /* @__PURE__ */ jsxs2("div", { className: "langley-actions", children: [
          /* @__PURE__ */ jsx3(
            "button",
            {
              className: "langley-btn langley-btn-primary",
              "data-testid": `chat-${agent.id}`,
              onClick: () => onChat?.(agent.id),
              children: "Chat"
            }
          ),
          /* @__PURE__ */ jsx3(
            "button",
            {
              className: "langley-btn",
              "data-testid": `stop-${agent.id}`,
              onClick: () => onAction?.(agent.id, "stop"),
              children: "Stop"
            }
          ),
          /* @__PURE__ */ jsx3(
            "button",
            {
              className: "langley-btn langley-btn-danger",
              "data-testid": `kill-${agent.id}`,
              onClick: () => onAction?.(agent.id, "kill"),
              children: "Kill"
            }
          ),
          /* @__PURE__ */ jsx3(
            "button",
            {
              className: "langley-btn",
              "data-testid": `restart-${agent.id}`,
              onClick: () => onAction?.(agent.id, "restart"),
              children: "Restart"
            }
          )
        ] }) })
      ] }, agent.id)) })
    ] })
  ] });
}

// src/ts/components/ActivityFeed.tsx
import { useRef, useEffect } from "react";
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
function formatTime(ts) {
  const d = new Date(ts * 1e3);
  return d.toLocaleTimeString();
}
function ActivityFeed({ events }) {
  const listRef = useRef(null);
  useEffect(() => {
    if (listRef.current) {
      listRef.current.scrollTop = listRef.current.scrollHeight;
    }
  }, [events]);
  if (events.length === 0) {
    return /* @__PURE__ */ jsx4("p", { className: "langley-empty", "data-testid": "no-activity", children: "No recent activity." });
  }
  return /* @__PURE__ */ jsxs3("div", { className: "langley-activity-feed", "data-testid": "activity-feed", children: [
    /* @__PURE__ */ jsx4("h2", { children: "Activity" }),
    /* @__PURE__ */ jsx4("ul", { className: "langley-activity-list", ref: listRef, children: events.map((ev) => /* @__PURE__ */ jsxs3(
      "li",
      {
        className: "langley-activity-item",
        "data-testid": `activity-${ev.id}`,
        children: [
          /* @__PURE__ */ jsx4("span", { className: "langley-activity-type", children: ev.event_type }),
          /* @__PURE__ */ jsx4("span", { className: "langley-activity-agent", children: ev.agent_id.slice(0, 8) }),
          /* @__PURE__ */ jsx4("span", { className: "langley-activity-time", children: formatTime(ev.timestamp) })
        ]
      },
      ev.id
    )) })
  ] });
}

// src/ts/components/LaunchDialog.tsx
import { useState as useState2, useEffect as useEffect2 } from "react";
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
function formatBilling(billing) {
  if (!billing) return "";
  if (billing.type === "multiplier") {
    if (billing.multiplier === 0) return "Included";
    return `${billing.multiplier}\xD7 premium`;
  }
  if (billing.type === "per_token") {
    return `$${billing.input_per_mtok} / $${billing.output_per_mtok} per MTok`;
  }
  return "";
}
function LaunchDialog({
  profiles,
  onLaunch,
  onClose
}) {
  const [selectedProfile, setSelectedProfile] = useState2("");
  const [preconfigured, setPreconfigured] = useState2([]);
  const [providers, setProviders] = useState2([]);
  const [showNewProfile, setShowNewProfile] = useState2(false);
  const [newName, setNewName] = useState2("");
  const [newTenant, setNewTenant] = useState2("default");
  const [newProvider, setNewProvider] = useState2("");
  const [newModel, setNewModel] = useState2("");
  const [newSystemPrompt, setNewSystemPrompt] = useState2("");
  const [newCommand, setNewCommand] = useState2("");
  const [creating, setCreating] = useState2(false);
  const [createError, setCreateError] = useState2(null);
  const providerOptions = [
    { value: "", label: "-- Select provider --" },
    ...providers.map((p) => ({ value: p.id, label: p.name })),
    { value: "custom", label: "Custom Command" }
  ];
  const selectedProviderInfo = providers.find((p) => p.id === newProvider);
  const providerModels = selectedProviderInfo?.models ?? [];
  const currentModelBilling = providerModels.find(
    (m) => m.id === newModel
  )?.billing;
  const isLLMProvider = newProvider && newProvider !== "custom";
  useEffect2(() => {
    fetchProviders().then(setProviders).catch(() => {
    });
    listPreconfiguredAgents().then(setPreconfigured).catch(() => {
    });
  }, []);
  const fillFromPreconfigured = (agent) => {
    setShowNewProfile(true);
    setNewName(agent.name);
    setNewProvider(agent.provider);
    setNewModel(agent.model);
    setNewSystemPrompt(agent.system_prompt);
  };
  const handleCreateProfile = async () => {
    if (!newName) return;
    if (!isLLMProvider && !newCommand) return;
    setCreating(true);
    setCreateError(null);
    try {
      const parts = newCommand ? newCommand.split(/\s+/).filter(Boolean) : [];
      const profile = await createProfile({
        name: newName,
        tenant_id: newTenant,
        command: parts,
        llm_provider: newProvider === "custom" ? "" : newProvider,
        model: newModel,
        system_prompt: newSystemPrompt
      });
      onLaunch(profile.id);
    } catch (err) {
      setCreateError(
        err instanceof Error ? err.message : "Failed to create profile"
      );
    } finally {
      setCreating(false);
    }
  };
  return /* @__PURE__ */ jsx5("div", { className: "langley-dialog-overlay", "data-testid": "launch-dialog", children: /* @__PURE__ */ jsxs4("div", { className: "langley-dialog", children: [
    /* @__PURE__ */ jsxs4("div", { className: "langley-dialog-header", children: [
      /* @__PURE__ */ jsx5("h2", { children: "Launch Agent" }),
      /* @__PURE__ */ jsx5(
        "button",
        {
          className: "langley-btn",
          onClick: onClose,
          "data-testid": "close-dialog",
          children: "\xD7"
        }
      )
    ] }),
    preconfigured.length > 0 && !showNewProfile && /* @__PURE__ */ jsxs4("div", { className: "langley-dialog-section", children: [
      /* @__PURE__ */ jsx5("label", { children: "Preconfigured agents:" }),
      /* @__PURE__ */ jsx5("div", { className: "langley-preconfigured-list", children: preconfigured.map((a) => /* @__PURE__ */ jsxs4(
        "button",
        {
          className: "langley-preconfigured-item",
          onClick: () => fillFromPreconfigured(a),
          "data-testid": `preconfigured-${a.name}`,
          children: [
            /* @__PURE__ */ jsx5("span", { className: "langley-preconfigured-name", children: a.name }),
            /* @__PURE__ */ jsx5("span", { className: "langley-preconfigured-provider", children: a.provider })
          ]
        },
        a.source
      )) })
    ] }),
    profiles.length > 0 && !showNewProfile && /* @__PURE__ */ jsxs4("div", { className: "langley-dialog-section", children: [
      /* @__PURE__ */ jsx5("label", { htmlFor: "profile-select", children: "Select a profile:" }),
      /* @__PURE__ */ jsxs4(
        "select",
        {
          id: "profile-select",
          value: selectedProfile,
          onChange: (e) => setSelectedProfile(e.target.value),
          "data-testid": "profile-select",
          children: [
            /* @__PURE__ */ jsx5("option", { value: "", children: "-- Choose --" }),
            profiles.map((p) => /* @__PURE__ */ jsxs4("option", { value: p.id, children: [
              p.name,
              " (v",
              p.version,
              ")"
            ] }, p.id))
          ]
        }
      ),
      /* @__PURE__ */ jsx5(
        "button",
        {
          className: "langley-btn langley-btn-primary",
          disabled: !selectedProfile,
          onClick: () => onLaunch(selectedProfile),
          "data-testid": "launch-btn",
          children: "Launch"
        }
      )
    ] }),
    /* @__PURE__ */ jsx5("div", { className: "langley-dialog-section", children: !showNewProfile ? /* @__PURE__ */ jsx5(
      "button",
      {
        className: "langley-btn",
        onClick: () => setShowNewProfile(true),
        "data-testid": "new-profile-toggle",
        children: "+ New Profile"
      }
    ) : /* @__PURE__ */ jsxs4("div", { className: "langley-new-profile", "data-testid": "new-profile-form", children: [
      /* @__PURE__ */ jsx5("h3", { children: "New Profile" }),
      /* @__PURE__ */ jsx5("label", { htmlFor: "np-name", children: "Name" }),
      /* @__PURE__ */ jsx5(
        "input",
        {
          id: "np-name",
          type: "text",
          value: newName,
          onChange: (e) => setNewName(e.target.value),
          placeholder: "my-agent",
          "data-testid": "np-name"
        }
      ),
      /* @__PURE__ */ jsx5("label", { htmlFor: "np-tenant", children: "Tenant ID" }),
      /* @__PURE__ */ jsx5(
        "input",
        {
          id: "np-tenant",
          type: "text",
          value: newTenant,
          onChange: (e) => setNewTenant(e.target.value),
          "data-testid": "np-tenant"
        }
      ),
      /* @__PURE__ */ jsx5("label", { htmlFor: "np-provider", children: "Provider" }),
      /* @__PURE__ */ jsx5(
        "select",
        {
          id: "np-provider",
          value: newProvider,
          onChange: (e) => {
            setNewProvider(e.target.value);
            setNewModel("");
          },
          "data-testid": "np-provider",
          children: providerOptions.map((p) => /* @__PURE__ */ jsx5("option", { value: p.value, children: p.label }, p.value))
        }
      ),
      newProvider && newProvider !== "custom" && /* @__PURE__ */ jsxs4(Fragment2, { children: [
        /* @__PURE__ */ jsx5("label", { htmlFor: "np-model", children: "Model" }),
        /* @__PURE__ */ jsx5(
          "input",
          {
            id: "np-model",
            type: "text",
            list: "np-model-suggestions",
            value: newModel,
            onChange: (e) => setNewModel(e.target.value),
            placeholder: "Type or select a model\u2026",
            "data-testid": "np-model",
            autoComplete: "off"
          }
        ),
        providerModels.length > 0 && /* @__PURE__ */ jsx5("datalist", { id: "np-model-suggestions", children: providerModels.map((m) => {
          const cost = formatBilling(m.billing);
          return /* @__PURE__ */ jsx5("option", { value: m.id, children: cost ? `${m.name} \u2014 ${cost}` : m.name }, m.id);
        }) }),
        currentModelBilling && /* @__PURE__ */ jsx5("span", { className: "langley-model-cost", children: formatBilling(currentModelBilling) })
      ] }),
      (!newProvider || newProvider === "custom") && /* @__PURE__ */ jsxs4(Fragment2, { children: [
        /* @__PURE__ */ jsx5("label", { htmlFor: "np-command", children: "Command" }),
        /* @__PURE__ */ jsx5(
          "input",
          {
            id: "np-command",
            type: "text",
            value: newCommand,
            onChange: (e) => setNewCommand(e.target.value),
            placeholder: "python agent.py",
            "data-testid": "np-command"
          }
        )
      ] }),
      /* @__PURE__ */ jsx5("label", { htmlFor: "np-prompt", children: "Instructions" }),
      /* @__PURE__ */ jsx5(
        "textarea",
        {
          id: "np-prompt",
          value: newSystemPrompt,
          onChange: (e) => setNewSystemPrompt(e.target.value),
          placeholder: "Describe what this agent should do...",
          rows: 4,
          "data-testid": "np-prompt"
        }
      ),
      createError && /* @__PURE__ */ jsx5("div", { className: "langley-error", children: createError }),
      /* @__PURE__ */ jsxs4("div", { className: "langley-actions", children: [
        /* @__PURE__ */ jsx5(
          "button",
          {
            className: "langley-btn langley-btn-primary",
            onClick: handleCreateProfile,
            disabled: creating || !newName || !isLLMProvider && !newCommand,
            "data-testid": "create-and-launch",
            children: creating ? "Creating..." : "Create & Launch"
          }
        ),
        /* @__PURE__ */ jsx5(
          "button",
          {
            className: "langley-btn",
            onClick: () => setShowNewProfile(false),
            children: "Cancel"
          }
        )
      ] })
    ] }) })
  ] }) });
}

// src/ts/components/StatusTab.tsx
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
function StatusTab({
  agents,
  activity,
  onAgentsChanged,
  onNavigateChat,
  onNavigateInspect,
  onBulkAction
}) {
  const [filter, setFilter] = useState3("all");
  const [showLaunch, setShowLaunch] = useState3(false);
  const [profiles, setProfiles] = useState3([]);
  const [error, setError] = useState3(null);
  const handleAction = useCallback2(
    async (agentId, action) => {
      try {
        if (action === "stop") await stopAgent(agentId);
        else if (action === "kill") await killAgent(agentId);
        else if (action === "restart") await restartAgent(agentId);
        onAgentsChanged();
      } catch (err) {
        setError(
          err instanceof Error ? err.message : `Failed to ${action} agent`
        );
      }
    },
    [onAgentsChanged]
  );
  const handleLaunch = useCallback2(
    async (profileId) => {
      try {
        await launchAgent(profileId);
        setShowLaunch(false);
        onAgentsChanged();
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to launch agent");
      }
    },
    [onAgentsChanged]
  );
  const openLaunchDialog = useCallback2(async () => {
    try {
      const p = await listProfiles();
      setProfiles(p);
    } catch {
      setProfiles([]);
    }
    setShowLaunch(true);
  }, []);
  const filteredAgents = filter === "all" ? agents : agents.filter((a) => a.status === filter);
  return /* @__PURE__ */ jsxs5(Fragment3, { children: [
    error && /* @__PURE__ */ jsxs5("div", { className: "langley-error", "data-testid": "error-banner", children: [
      error,
      /* @__PURE__ */ jsx6(
        "button",
        {
          className: "langley-btn",
          onClick: () => setError(null),
          style: { marginLeft: 8 },
          children: "Dismiss"
        }
      )
    ] }),
    /* @__PURE__ */ jsx6(SummaryCards, { agents }),
    /* @__PURE__ */ jsxs5("div", { className: "langley-controls", children: [
      /* @__PURE__ */ jsx6("label", { htmlFor: "status-filter", children: "Filter by status: " }),
      /* @__PURE__ */ jsxs5(
        "select",
        {
          id: "status-filter",
          value: filter,
          onChange: (e) => setFilter(e.target.value),
          "data-testid": "status-filter",
          children: [
            /* @__PURE__ */ jsx6("option", { value: "all", children: "All" }),
            /* @__PURE__ */ jsx6("option", { value: "running", children: "Running" }),
            /* @__PURE__ */ jsx6("option", { value: "stopped", children: "Stopped" }),
            /* @__PURE__ */ jsx6("option", { value: "errored", children: "Errored" }),
            /* @__PURE__ */ jsx6("option", { value: "pending", children: "Pending" })
          ]
        }
      ),
      /* @__PURE__ */ jsx6(
        "button",
        {
          className: "langley-btn langley-btn-primary",
          onClick: openLaunchDialog,
          "data-testid": "open-launch",
          children: "+ Launch Agent"
        }
      )
    ] }),
    /* @__PURE__ */ jsx6(
      AgentTable,
      {
        agents: filteredAgents,
        onAction: handleAction,
        onChat: onNavigateChat,
        onInspect: onNavigateInspect,
        onBulkAction
      }
    ),
    /* @__PURE__ */ jsx6(ActivityFeed, { events: activity }),
    showLaunch && /* @__PURE__ */ jsx6(
      LaunchDialog,
      {
        profiles,
        onLaunch: handleLaunch,
        onClose: () => setShowLaunch(false)
      }
    )
  ] });
}

// src/ts/components/ChatTab.tsx
import { useState as useState5, useCallback as useCallback4 } from "react";

// src/ts/components/ChatPanel.tsx
import { useState as useState4, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef2 } from "react";
import { marked } from "marked";
import DOMPurify from "dompurify";
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
marked.setOptions({ breaks: true, gfm: true });
function renderMarkdown(text) {
  const raw = marked.parse(text);
  return DOMPurify.sanitize(raw);
}
function inboxToChatMessages(msgs) {
  const result = [];
  for (const msg of msgs) {
    const body = msg.body;
    const text = body.text ?? body.body ?? "";
    if (!text) continue;
    result.push({
      id: msg.id,
      role: "user",
      content: text,
      timestamp: msg.timestamp ?? Date.now() / 1e3
    });
  }
  return result;
}
function outboxToChatMessages(msgs) {
  const result = [];
  let pending = "";
  for (const msg of msgs) {
    const body = msg.body;
    const type = body.type ?? "";
    if (type === "delta") {
      pending += body.content ?? "";
    } else if (type === "message" || type === "turn_complete") {
      const content = pending || body.content || "";
      pending = "";
      if (content) {
        result.push({
          id: msg.id,
          role: "assistant",
          content,
          timestamp: body.timestamp ?? msg.timestamp ?? Date.now() / 1e3,
          type: "message"
        });
      }
    } else if (type === "tool_start") {
      result.push({
        id: msg.id,
        role: "system",
        content: `Using tool: ${body.tool_name}`,
        timestamp: body.timestamp ?? msg.timestamp ?? Date.now() / 1e3,
        type: "tool"
      });
    } else if (type === "error") {
      result.push({
        id: msg.id,
        role: "system",
        content: `Error: ${body.message}`,
        timestamp: body.timestamp ?? msg.timestamp ?? Date.now() / 1e3,
        type: "error"
      });
    }
  }
  return result;
}
function mergeMessages(existing, incoming) {
  const map = /* @__PURE__ */ new Map();
  for (const m of existing) map.set(m.id, m);
  for (const m of incoming) map.set(m.id, m);
  return Array.from(map.values()).sort((a, b) => a.timestamp - b.timestamp);
}
function ChatMessageBubble({ msg }) {
  const [showRaw, setShowRaw] = useState4(false);
  return /* @__PURE__ */ jsxs6(
    "div",
    {
      className: `langley-chat-message langley-chat-${msg.role}`,
      "data-testid": `chat-msg-${msg.id}`,
      children: [
        /* @__PURE__ */ jsxs6("div", { className: "langley-chat-meta", children: [
          /* @__PURE__ */ jsx7("span", { className: "langley-chat-role", children: msg.role }),
          /* @__PURE__ */ jsx7(
            "button",
            {
              className: "langley-chat-raw-toggle",
              onClick: () => setShowRaw((v) => !v),
              title: showRaw ? "Show rendered" : "Show raw",
              "data-testid": `chat-raw-toggle-${msg.id}`,
              children: showRaw ? "rendered" : "raw"
            }
          )
        ] }),
        showRaw ? /* @__PURE__ */ jsx7("pre", { className: "langley-chat-content langley-chat-raw", children: msg.content }) : /* @__PURE__ */ jsx7(
          "div",
          {
            className: "langley-chat-content langley-chat-markdown",
            dangerouslySetInnerHTML: { __html: renderMarkdown(msg.content) }
          }
        )
      ]
    }
  );
}
function ChatPanel({
  agentId,
  agentName,
  wsClient,
  onClose
}) {
  const [messages, setMessages] = useState4([]);
  const [input, setInput] = useState4("");
  const [sending, setSending] = useState4(false);
  const outboxSeqRef = useRef2(0);
  const inboxSeqRef = useRef2(0);
  const messagesEndRef = useRef2(null);
  const pendingContentRef = useRef2("");
  const scrollToBottom = useCallback3(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, []);
  useEffect3(() => {
    setMessages([]);
    outboxSeqRef.current = 0;
    inboxSeqRef.current = 0;
    pendingContentRef.current = "";
  }, [agentId]);
  useEffect3(() => {
    const outboxChannel = `agent.${agentId}.outbox`;
    const inboxChannel = `agent.${agentId}.inbox`;
    const poll = async () => {
      try {
        const outboxMsgs = await queryMessages(outboxChannel, {
          from_seq: outboxSeqRef.current,
          limit: 100
        });
        const inboxMsgs = await queryMessages(inboxChannel, {
          from_seq: inboxSeqRef.current,
          limit: 100
        });
        for (const m of outboxMsgs) {
          if (m.sequence > outboxSeqRef.current)
            outboxSeqRef.current = m.sequence;
        }
        for (const m of inboxMsgs) {
          if (m.sequence > inboxSeqRef.current)
            inboxSeqRef.current = m.sequence;
        }
        const assistantMsgs = outboxToChatMessages(
          outboxMsgs.map((m) => ({
            id: m.id,
            body: m.body,
            timestamp: m.timestamp
          }))
        );
        const userMsgs = inboxToChatMessages(inboxMsgs);
        const incoming = [...assistantMsgs, ...userMsgs];
        if (incoming.length > 0) {
          setMessages((prev) => mergeMessages(prev, incoming));
        }
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 3e3);
    let unsubWs;
    if (wsClient) {
      unsubWs = wsClient.subscribe(outboxChannel, (data) => {
        const seq = data.sequence ?? 0;
        if (seq && seq <= outboxSeqRef.current) return;
        if (seq > outboxSeqRef.current) outboxSeqRef.current = seq;
        const body = data.body ?? data;
        const id = data.id ?? `ws-${Date.now()}`;
        const type = body.type ?? "";
        if (type === "delta") {
          pendingContentRef.current += body.content ?? "";
          return;
        }
        const incoming = outboxToChatMessages([
          { id, body, timestamp: body.timestamp }
        ]);
        if ((type === "message" || type === "turn_complete") && pendingContentRef.current) {
          const content = pendingContentRef.current;
          pendingContentRef.current = "";
          if (content) {
            const ts = body.timestamp ?? Date.now() / 1e3;
            setMessages(
              (prev) => mergeMessages(prev, [
                {
                  id,
                  role: "assistant",
                  content,
                  timestamp: ts,
                  type: "message"
                }
              ])
            );
            return;
          }
        }
        if (incoming.length > 0) {
          setMessages((prev) => mergeMessages(prev, incoming));
        }
      });
    }
    return () => {
      clearInterval(interval);
      unsubWs?.();
    };
  }, [agentId, wsClient]);
  useEffect3(() => {
    scrollToBottom();
  }, [messages, scrollToBottom]);
  const handleSend = async () => {
    const text = input.trim();
    if (!text || sending) return;
    setSending(true);
    setInput("");
    const tempId = `user-${Date.now()}`;
    const userMsg = {
      id: tempId,
      role: "user",
      content: text,
      timestamp: Date.now() / 1e3
    };
    setMessages((prev) => mergeMessages(prev, [userMsg]));
    try {
      const receipt = await sendMessageToAgent(agentId, { text });
      setMessages(
        (prev) => prev.map(
          (m) => m.id === tempId ? { ...m, id: receipt.message_id } : m
        )
      );
    } catch {
      setMessages((prev) => [
        ...prev,
        {
          id: `err-${Date.now()}`,
          role: "system",
          content: "Failed to send message",
          timestamp: Date.now() / 1e3,
          type: "error"
        }
      ]);
    } finally {
      setSending(false);
    }
  };
  return /* @__PURE__ */ jsxs6("div", { className: "langley-chat-panel", "data-testid": "chat-panel", children: [
    /* @__PURE__ */ jsxs6("div", { className: "langley-chat-header", children: [
      /* @__PURE__ */ jsxs6("h3", { children: [
        "Chat \u2014 ",
        agentName
      ] }),
      onClose && /* @__PURE__ */ jsx7(
        "button",
        {
          className: "langley-btn",
          onClick: onClose,
          "data-testid": "close-chat",
          children: "\xD7"
        }
      )
    ] }),
    /* @__PURE__ */ jsxs6("div", { className: "langley-chat-messages", "data-testid": "chat-messages", children: [
      messages.length === 0 && /* @__PURE__ */ jsx7("p", { className: "langley-empty", children: "No messages yet. Send a prompt to get started." }),
      messages.map((msg) => /* @__PURE__ */ jsx7(ChatMessageBubble, { msg }, msg.id)),
      /* @__PURE__ */ jsx7("div", { ref: messagesEndRef })
    ] }),
    /* @__PURE__ */ jsxs6("div", { className: "langley-chat-input", children: [
      /* @__PURE__ */ jsx7(
        "input",
        {
          type: "text",
          value: input,
          onChange: (e) => setInput(e.target.value),
          onKeyDown: (e) => {
            if (e.key === "Enter" && !e.shiftKey) {
              e.preventDefault();
              handleSend();
            }
          },
          placeholder: "Type a message...",
          disabled: sending,
          "data-testid": "chat-input"
        }
      ),
      /* @__PURE__ */ jsx7(
        "button",
        {
          className: "langley-btn langley-btn-primary",
          onClick: handleSend,
          disabled: sending || !input.trim(),
          "data-testid": "chat-send",
          children: "Send"
        }
      )
    ] })
  ] });
}

// src/ts/components/ChatTab.tsx
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
function ChatTab({
  agents,
  initialAgentId,
  wsClient
}) {
  const [sessions, setSessions] = useState5(() => {
    if (initialAgentId) {
      const agent = agents.find((a) => a.id === initialAgentId);
      return [
        { agentId: initialAgentId, agentName: agent?.name ?? initialAgentId }
      ];
    }
    return [];
  });
  const [activeSessionIdx, setActiveSessionIdx] = useState5(0);
  const [selectedAgent, setSelectedAgent] = useState5("");
  const runningAgents = agents.filter((a) => a.status === "running");
  const openSession = useCallback4(
    (agentId) => {
      const existing = sessions.findIndex((s) => s.agentId === agentId);
      if (existing >= 0) {
        setActiveSessionIdx(existing);
        return;
      }
      const agent = agents.find((a) => a.id === agentId);
      const newSession = { agentId, agentName: agent?.name ?? agentId };
      setSessions((prev) => [...prev, newSession]);
      setActiveSessionIdx(sessions.length);
      setSelectedAgent("");
    },
    [sessions, agents]
  );
  const closeSession = useCallback4((idx) => {
    setSessions((prev) => prev.filter((_, i) => i !== idx));
    setActiveSessionIdx((prev) => {
      if (idx < prev) return prev - 1;
      if (idx === prev) return Math.max(0, prev - 1);
      return prev;
    });
  }, []);
  const activeSession = sessions[activeSessionIdx] ?? null;
  return /* @__PURE__ */ jsxs7("div", { className: "langley-chat-tab", "data-testid": "chat-tab", children: [
    /* @__PURE__ */ jsxs7("div", { className: "langley-chat-tab-header", children: [
      /* @__PURE__ */ jsx8("label", { htmlFor: "chat-agent-select", children: "Agent: " }),
      /* @__PURE__ */ jsxs7(
        "select",
        {
          id: "chat-agent-select",
          value: selectedAgent,
          onChange: (e) => setSelectedAgent(e.target.value),
          "data-testid": "chat-agent-select",
          children: [
            /* @__PURE__ */ jsx8("option", { value: "", children: "-- Select agent --" }),
            runningAgents.map((a) => /* @__PURE__ */ jsxs7("option", { value: a.id, children: [
              a.name,
              " (",
              a.id.slice(0, 8),
              ")"
            ] }, a.id))
          ]
        }
      ),
      /* @__PURE__ */ jsx8(
        "button",
        {
          className: "langley-btn langley-btn-primary",
          disabled: !selectedAgent,
          onClick: () => selectedAgent && openSession(selectedAgent),
          "data-testid": "open-chat-session",
          children: "Open Chat"
        }
      )
    ] }),
    sessions.length > 0 && /* @__PURE__ */ jsx8("div", { className: "langley-chat-sessions", "data-testid": "chat-sessions", children: sessions.map((s, idx) => /* @__PURE__ */ jsxs7(
      "div",
      {
        className: `langley-chat-session-tab${idx === activeSessionIdx ? " active" : ""}`,
        "data-testid": `chat-session-${s.agentId}`,
        children: [
          /* @__PURE__ */ jsx8(
            "button",
            {
              className: "langley-chat-session-label",
              onClick: () => setActiveSessionIdx(idx),
              children: s.agentName
            }
          ),
          /* @__PURE__ */ jsx8(
            "button",
            {
              className: "langley-chat-session-close",
              onClick: () => closeSession(idx),
              title: "Close session",
              children: "\xD7"
            }
          )
        ]
      },
      s.agentId
    )) }),
    /* @__PURE__ */ jsx8("div", { className: "langley-chat-tab-body", children: activeSession ? /* @__PURE__ */ jsx8(
      ChatPanel,
      {
        agentId: activeSession.agentId,
        agentName: activeSession.agentName,
        wsClient
      }
    ) : /* @__PURE__ */ jsx8("div", { className: "langley-empty", "data-testid": "no-chat-agent", children: runningAgents.length === 0 ? "No running agents. Launch an agent from the Status tab first." : "Select an agent and click Open Chat to start a session." }) })
  ] });
}

// src/ts/components/LogsTab.tsx
import { useState as useState6, useEffect as useEffect4, useRef as useRef3, useCallback as useCallback5 } from "react";
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
function parseLogEntry(msg) {
  const body = msg.body;
  return {
    id: msg.id,
    timestamp: body.timestamp ?? msg.timestamp,
    level: (body.level ?? body.type ?? "info").toLowerCase(),
    message: body.message ?? body.content ?? JSON.stringify(body)
  };
}
function parseMessageEntry(msg, agentId) {
  const body = msg.body;
  return {
    id: msg.id,
    timestamp: msg.timestamp,
    channel: msg.channel,
    direction: msg.channel.endsWith(".inbox") ? "in" : "out",
    body: body.text ?? body.content ?? body.message ?? JSON.stringify(body)
  };
}
function formatTimestamp(ts) {
  const d = new Date(ts * 1e3);
  return d.toLocaleTimeString();
}
function LogsTab({ agents }) {
  const [selectedAgent, setSelectedAgent] = useState6("");
  const [view, setView] = useState6("logs");
  const [logs, setLogs] = useState6([]);
  const [messageEntries, setMessageEntries] = useState6([]);
  const [auditEntries, setAuditEntries] = useState6([]);
  const [levelFilter, setLevelFilter] = useState6("all");
  const [search, setSearch] = useState6("");
  const seqRef = useRef3(0);
  const msgSeqInRef = useRef3(0);
  const msgSeqOutRef = useRef3(0);
  const logsEndRef = useRef3(null);
  const [autoScroll, setAutoScroll] = useState6(true);
  useEffect4(() => {
    setLogs([]);
    setMessageEntries([]);
    setAuditEntries([]);
    seqRef.current = 0;
    msgSeqInRef.current = 0;
    msgSeqOutRef.current = 0;
  }, [selectedAgent, view]);
  useEffect4(() => {
    if (!selectedAgent || view !== "logs") return;
    const channels = [
      `agent.${selectedAgent}.outbox`,
      `agent.${selectedAgent}.inbox`
    ];
    const poll = async () => {
      try {
        const newLogs = [];
        for (const channel of channels) {
          const msgs = await queryMessages(channel, {
            from_seq: seqRef.current,
            limit: 100
          });
          for (const msg of msgs) {
            if (msg.sequence > seqRef.current) seqRef.current = msg.sequence;
            newLogs.push(parseLogEntry(msg));
          }
        }
        if (newLogs.length > 0) {
          setLogs((prev) => [...prev, ...newLogs]);
        }
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 2e3);
    return () => clearInterval(interval);
  }, [selectedAgent, view]);
  useEffect4(() => {
    if (!selectedAgent || view !== "messages") return;
    const poll = async () => {
      try {
        const newEntries = [];
        const inboxMsgs = await queryMessages(`agent.${selectedAgent}.inbox`, {
          from_seq: msgSeqInRef.current,
          limit: 100
        });
        for (const msg of inboxMsgs) {
          if (msg.sequence > msgSeqInRef.current)
            msgSeqInRef.current = msg.sequence;
          newEntries.push(parseMessageEntry(msg, selectedAgent));
        }
        const outboxMsgs = await queryMessages(
          `agent.${selectedAgent}.outbox`,
          {
            from_seq: msgSeqOutRef.current,
            limit: 100
          }
        );
        for (const msg of outboxMsgs) {
          if (msg.sequence > msgSeqOutRef.current)
            msgSeqOutRef.current = msg.sequence;
          newEntries.push(parseMessageEntry(msg, selectedAgent));
        }
        if (newEntries.length > 0) {
          newEntries.sort((a, b) => a.timestamp - b.timestamp);
          setMessageEntries((prev) => [...prev, ...newEntries]);
        }
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 2e3);
    return () => clearInterval(interval);
  }, [selectedAgent, view]);
  useEffect4(() => {
    if (!selectedAgent || view !== "audit") return;
    const poll = async () => {
      try {
        const entries = await queryAudit("default", {
          agent_id: selectedAgent,
          limit: 200
        });
        setAuditEntries(entries);
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 3e3);
    return () => clearInterval(interval);
  }, [selectedAgent, view]);
  const scrollToBottom = useCallback5(() => {
    if (autoScroll) {
      logsEndRef.current?.scrollIntoView({ behavior: "smooth" });
    }
  }, [autoScroll]);
  useEffect4(() => {
    scrollToBottom();
  }, [logs, messageEntries, auditEntries, scrollToBottom]);
  const filteredLogs = logs.filter((entry) => {
    if (levelFilter !== "all" && entry.level !== levelFilter) return false;
    if (search && !entry.message.toLowerCase().includes(search.toLowerCase()))
      return false;
    return true;
  });
  return /* @__PURE__ */ jsxs8("div", { className: "langley-logs-tab", "data-testid": "logs-tab", children: [
    /* @__PURE__ */ jsxs8("div", { className: "langley-logs-controls", children: [
      /* @__PURE__ */ jsx9("label", { htmlFor: "logs-agent-select", children: "Agent: " }),
      /* @__PURE__ */ jsxs8(
        "select",
        {
          id: "logs-agent-select",
          value: selectedAgent,
          onChange: (e) => setSelectedAgent(e.target.value),
          "data-testid": "logs-agent-select",
          children: [
            /* @__PURE__ */ jsx9("option", { value: "", children: "-- Select agent --" }),
            agents.map((a) => /* @__PURE__ */ jsxs8("option", { value: a.id, children: [
              a.name,
              " (",
              a.id.slice(0, 8),
              ")"
            ] }, a.id))
          ]
        }
      ),
      /* @__PURE__ */ jsx9("label", { htmlFor: "logs-view-select", children: "View: " }),
      /* @__PURE__ */ jsxs8(
        "select",
        {
          id: "logs-view-select",
          value: view,
          onChange: (e) => setView(e.target.value),
          "data-testid": "logs-view-select",
          children: [
            /* @__PURE__ */ jsx9("option", { value: "logs", children: "Logs" }),
            /* @__PURE__ */ jsx9("option", { value: "messages", children: "Messages" }),
            /* @__PURE__ */ jsx9("option", { value: "audit", children: "Audit Trail" })
          ]
        }
      ),
      view === "logs" && /* @__PURE__ */ jsxs8(Fragment4, { children: [
        /* @__PURE__ */ jsx9("label", { htmlFor: "logs-level-filter", children: "Level: " }),
        /* @__PURE__ */ jsxs8(
          "select",
          {
            id: "logs-level-filter",
            value: levelFilter,
            onChange: (e) => setLevelFilter(e.target.value),
            "data-testid": "logs-level-filter",
            children: [
              /* @__PURE__ */ jsx9("option", { value: "all", children: "All" }),
              /* @__PURE__ */ jsx9("option", { value: "info", children: "Info" }),
              /* @__PURE__ */ jsx9("option", { value: "error", children: "Error" }),
              /* @__PURE__ */ jsx9("option", { value: "message", children: "Message" }),
              /* @__PURE__ */ jsx9("option", { value: "tool", children: "Tool" }),
              /* @__PURE__ */ jsx9("option", { value: "delta", children: "Delta" })
            ]
          }
        )
      ] }),
      /* @__PURE__ */ jsx9(
        "input",
        {
          type: "text",
          value: search,
          onChange: (e) => setSearch(e.target.value),
          placeholder: "Search...",
          className: "langley-logs-search",
          "data-testid": "logs-search"
        }
      ),
      /* @__PURE__ */ jsxs8("label", { className: "langley-logs-autoscroll", children: [
        /* @__PURE__ */ jsx9(
          "input",
          {
            type: "checkbox",
            checked: autoScroll,
            onChange: (e) => setAutoScroll(e.target.checked)
          }
        ),
        "Auto-scroll"
      ] })
    ] }),
    /* @__PURE__ */ jsxs8("div", { className: "langley-logs-stream", "data-testid": "logs-stream", children: [
      !selectedAgent ? /* @__PURE__ */ jsxs8("div", { className: "langley-empty", children: [
        "Select an agent to view ",
        view,
        "."
      ] }) : view === "logs" ? filteredLogs.length === 0 ? /* @__PURE__ */ jsx9("div", { className: "langley-empty", children: "No log entries yet." }) : filteredLogs.map((entry) => /* @__PURE__ */ jsxs8(
        "div",
        {
          className: `langley-log-entry langley-log-${entry.level}`,
          "data-testid": `log-${entry.id}`,
          children: [
            /* @__PURE__ */ jsx9("span", { className: "langley-log-time", children: formatTimestamp(entry.timestamp) }),
            /* @__PURE__ */ jsx9("span", { className: "langley-log-level", children: entry.level }),
            /* @__PURE__ */ jsx9("span", { className: "langley-log-message", children: entry.message })
          ]
        },
        entry.id
      )) : view === "messages" ? messageEntries.length === 0 ? /* @__PURE__ */ jsx9("div", { className: "langley-empty", children: "No messages yet." }) : messageEntries.filter(
        (m) => !search || m.body.toLowerCase().includes(search.toLowerCase())
      ).map((entry) => /* @__PURE__ */ jsxs8(
        "div",
        {
          className: `langley-log-entry langley-msg-${entry.direction}`,
          "data-testid": `msg-${entry.id}`,
          children: [
            /* @__PURE__ */ jsx9("span", { className: "langley-log-time", children: formatTimestamp(entry.timestamp) }),
            /* @__PURE__ */ jsx9("span", { className: "langley-log-level", children: entry.direction === "in" ? "\u2190 IN" : "\u2192 OUT" }),
            /* @__PURE__ */ jsx9("span", { className: "langley-log-message", children: entry.body })
          ]
        },
        entry.id
      )) : auditEntries.length === 0 ? /* @__PURE__ */ jsx9("div", { className: "langley-empty", children: "No audit entries yet." }) : auditEntries.filter(
        (a) => !search || a.event_type.toLowerCase().includes(search.toLowerCase()) || JSON.stringify(a.payload).toLowerCase().includes(search.toLowerCase())
      ).map((entry) => /* @__PURE__ */ jsxs8(
        "div",
        {
          className: "langley-log-entry langley-log-audit",
          "data-testid": `audit-${entry.id}`,
          children: [
            /* @__PURE__ */ jsx9("span", { className: "langley-log-time", children: formatTimestamp(entry.timestamp) }),
            /* @__PURE__ */ jsx9("span", { className: "langley-log-level", children: entry.event_type }),
            /* @__PURE__ */ jsx9("span", { className: "langley-log-message", children: JSON.stringify(entry.payload) })
          ]
        },
        entry.id
      )),
      /* @__PURE__ */ jsx9("div", { ref: logsEndRef })
    ] })
  ] });
}

// src/ts/components/ProfilesTab.tsx
import { useState as useState7, useEffect as useEffect5, useCallback as useCallback6 } from "react";
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
function ProfilesTab() {
  const [profiles, setProfiles] = useState7([]);
  const [preconfigured, setPreconfigured] = useState7([]);
  const [selected, setSelected] = useState7(null);
  const [error, setError] = useState7(null);
  const [loading, setLoading] = useState7(true);
  const [runningAgents, setRunningAgents] = useState7([]);
  const [saveFeedback, setSaveFeedback] = useState7(null);
  const [editing, setEditing] = useState7(false);
  const [rawEditing, setRawEditing] = useState7(false);
  const [rawContent, setRawContent] = useState7("");
  const [editFields, setEditFields] = useState7({ name: "", llm_provider: "", model: "", system_prompt: "" });
  const refresh = useCallback6(async () => {
    setLoading(true);
    try {
      const [p, pc, agents] = await Promise.all([
        listProfiles(),
        listPreconfiguredAgents().catch(() => []),
        listAgents(void 0, "running").catch(() => [])
      ]);
      setProfiles(p);
      setPreconfigured(pc);
      setRunningAgents(agents);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load profiles");
    } finally {
      setLoading(false);
    }
  }, []);
  useEffect5(() => {
    refresh();
  }, [refresh]);
  const handleDelete = async (id) => {
    try {
      await deleteProfile(id);
      if (selected?.id === id) setSelected(null);
      await refresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to delete profile");
    }
  };
  const handleImport = async (agent) => {
    try {
      await createProfile({
        name: agent.name,
        tenant_id: "default",
        command: [],
        llm_provider: agent.provider,
        model: agent.model,
        system_prompt: agent.system_prompt
      });
      await refresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to import profile");
    }
  };
  const handleLaunch = async (profileId) => {
    try {
      await launchAgent(profileId);
      window.location.hash = "#/status";
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to launch agent");
    }
  };
  const handleSaveToAgentsDir = async (profile) => {
    try {
      const result = await saveAgentToDisk({
        name: profile.name,
        provider: profile.llm_provider,
        model: profile.model,
        system_prompt: profile.system_prompt
      });
      setSaveFeedback(`Saved to ${result.path}`);
      setTimeout(() => setSaveFeedback(null), 4e3);
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Failed to save to agents dir"
      );
    }
  };
  const handleSaveToDisk = async (profile) => {
    const path = prompt(
      "Enter file path to save to:",
      `~/.langley/agents/${profile.name}.md`
    );
    if (!path) return;
    try {
      const result = await saveAgentToDisk({
        name: profile.name,
        provider: profile.llm_provider,
        model: profile.model,
        system_prompt: profile.system_prompt,
        path
      });
      setSaveFeedback(`Saved to ${result.path}`);
      setTimeout(() => setSaveFeedback(null), 4e3);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to save to disk");
    }
  };
  const handleGenerateProfile = async (agentId) => {
    try {
      await generateAgentProfile(agentId);
      setSaveFeedback(
        "Profile generation prompt sent \u2014 check the agent's chat for results."
      );
      setTimeout(() => setSaveFeedback(null), 5e3);
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Failed to send profile generation prompt"
      );
    }
  };
  const startEditing = (profile) => {
    setEditing(true);
    setRawEditing(false);
    setEditFields({
      name: profile.name,
      llm_provider: profile.llm_provider,
      model: profile.model,
      system_prompt: profile.system_prompt
    });
  };
  const startRawEditing = (profile) => {
    setRawEditing(true);
    setEditing(false);
    setRawContent(
      JSON.stringify(
        {
          name: profile.name,
          llm_provider: profile.llm_provider,
          model: profile.model,
          system_prompt: profile.system_prompt,
          command: profile.command,
          environment: profile.environment,
          tags: profile.tags
        },
        null,
        2
      )
    );
  };
  const cancelEditing = () => {
    setEditing(false);
    setRawEditing(false);
  };
  const handleSaveRaw = async () => {
    if (!selected) return;
    try {
      const parsed = JSON.parse(rawContent);
      const updated = await updateProfile(selected.id, parsed);
      setSelected(updated);
      setRawEditing(false);
      await refresh();
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Invalid JSON or failed to update"
      );
    }
  };
  const handleSaveEdit = async () => {
    if (!selected) return;
    try {
      const updated = await updateProfile(selected.id, editFields);
      setSelected(updated);
      setEditing(false);
      await refresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to update profile");
    }
  };
  return /* @__PURE__ */ jsxs9("div", { className: "langley-profiles-tab", "data-testid": "profiles-tab", children: [
    error && /* @__PURE__ */ jsxs9("div", { className: "langley-error", children: [
      error,
      /* @__PURE__ */ jsx10(
        "button",
        {
          className: "langley-btn",
          onClick: () => setError(null),
          style: { marginLeft: 8 },
          children: "Dismiss"
        }
      )
    ] }),
    saveFeedback && /* @__PURE__ */ jsx10("div", { className: "langley-save-feedback", "data-testid": "save-feedback", children: saveFeedback }),
    /* @__PURE__ */ jsxs9("div", { className: "langley-profiles-layout", children: [
      /* @__PURE__ */ jsxs9("div", { className: "langley-profiles-list", children: [
        /* @__PURE__ */ jsx10("h2", { children: "Saved Profiles" }),
        loading ? /* @__PURE__ */ jsx10("p", { className: "langley-empty", children: "Loading..." }) : profiles.length === 0 ? /* @__PURE__ */ jsx10("p", { className: "langley-empty", children: "No profiles saved." }) : /* @__PURE__ */ jsx10("ul", { className: "langley-profile-items", children: profiles.map((p) => /* @__PURE__ */ jsxs9(
          "li",
          {
            className: `langley-profile-item${selected?.id === p.id ? " active" : ""}`,
            "data-testid": `profile-${p.id}`,
            children: [
              /* @__PURE__ */ jsxs9(
                "button",
                {
                  className: "langley-profile-select",
                  onClick: () => setSelected(p),
                  children: [
                    /* @__PURE__ */ jsx10("span", { className: "langley-profile-name", children: p.name }),
                    /* @__PURE__ */ jsxs9("span", { className: "langley-profile-meta", children: [
                      "v",
                      p.version,
                      " \xB7 ",
                      p.llm_provider || "custom"
                    ] })
                  ]
                }
              ),
              /* @__PURE__ */ jsxs9("div", { className: "langley-profile-actions", children: [
                /* @__PURE__ */ jsx10(
                  "button",
                  {
                    className: "langley-btn langley-btn-primary",
                    onClick: () => handleLaunch(p.id),
                    title: "Launch agent with this profile",
                    children: "\u25B6"
                  }
                ),
                /* @__PURE__ */ jsx10(
                  "button",
                  {
                    className: "langley-btn langley-btn-danger",
                    onClick: () => handleDelete(p.id),
                    "data-testid": `delete-profile-${p.id}`,
                    title: "Delete profile",
                    children: "\xD7"
                  }
                )
              ] })
            ]
          },
          p.id
        )) }),
        preconfigured.length > 0 && /* @__PURE__ */ jsxs9(Fragment5, { children: [
          /* @__PURE__ */ jsx10("h2", { children: "Discovered Agents" }),
          /* @__PURE__ */ jsx10("ul", { className: "langley-profile-items", children: preconfigured.map((a) => /* @__PURE__ */ jsxs9(
            "li",
            {
              className: "langley-profile-item langley-profile-preconfigured",
              "data-testid": `preconfigured-${a.name}`,
              children: [
                /* @__PURE__ */ jsxs9("div", { className: "langley-profile-select", children: [
                  /* @__PURE__ */ jsx10("span", { className: "langley-profile-name", children: a.name }),
                  /* @__PURE__ */ jsx10("span", { className: "langley-profile-meta", children: a.provider })
                ] }),
                /* @__PURE__ */ jsx10("div", { className: "langley-profile-actions", children: /* @__PURE__ */ jsx10(
                  "button",
                  {
                    className: "langley-btn langley-btn-primary",
                    onClick: () => handleImport(a),
                    title: "Import as profile",
                    children: "Import"
                  }
                ) })
              ]
            },
            a.source
          )) })
        ] })
      ] }),
      /* @__PURE__ */ jsx10("div", { className: "langley-profile-detail", children: selected ? /* @__PURE__ */ jsxs9("div", { "data-testid": "profile-detail", children: [
        /* @__PURE__ */ jsx10("h2", { children: selected.name }),
        editing ? /* @__PURE__ */ jsxs9(
          "div",
          {
            className: "langley-profile-edit",
            "data-testid": "profile-edit-form",
            children: [
              /* @__PURE__ */ jsxs9("label", { children: [
                "Name",
                /* @__PURE__ */ jsx10(
                  "input",
                  {
                    type: "text",
                    value: editFields.name,
                    onChange: (e) => setEditFields({ ...editFields, name: e.target.value }),
                    "data-testid": "edit-name"
                  }
                )
              ] }),
              /* @__PURE__ */ jsxs9("label", { children: [
                "Provider",
                /* @__PURE__ */ jsx10(
                  "input",
                  {
                    type: "text",
                    value: editFields.llm_provider,
                    onChange: (e) => setEditFields({
                      ...editFields,
                      llm_provider: e.target.value
                    }),
                    "data-testid": "edit-provider"
                  }
                )
              ] }),
              /* @__PURE__ */ jsxs9("label", { children: [
                "Model",
                /* @__PURE__ */ jsx10(
                  "input",
                  {
                    type: "text",
                    value: editFields.model,
                    onChange: (e) => setEditFields({ ...editFields, model: e.target.value }),
                    "data-testid": "edit-model"
                  }
                )
              ] }),
              /* @__PURE__ */ jsxs9("label", { children: [
                "System Prompt",
                /* @__PURE__ */ jsx10(
                  "textarea",
                  {
                    value: editFields.system_prompt,
                    onChange: (e) => setEditFields({
                      ...editFields,
                      system_prompt: e.target.value
                    }),
                    rows: 6,
                    "data-testid": "edit-system-prompt"
                  }
                )
              ] }),
              /* @__PURE__ */ jsxs9("div", { className: "langley-actions", style: { marginTop: 12 }, children: [
                /* @__PURE__ */ jsx10(
                  "button",
                  {
                    className: "langley-btn langley-btn-primary",
                    onClick: handleSaveEdit,
                    "data-testid": "save-edit",
                    children: "Save"
                  }
                ),
                /* @__PURE__ */ jsx10("button", { className: "langley-btn", onClick: cancelEditing, children: "Cancel" })
              ] })
            ]
          }
        ) : rawEditing ? /* @__PURE__ */ jsxs9(
          "div",
          {
            className: "langley-profile-edit",
            "data-testid": "profile-raw-editor",
            children: [
              /* @__PURE__ */ jsxs9("label", { children: [
                "Raw JSON",
                /* @__PURE__ */ jsx10(
                  "textarea",
                  {
                    value: rawContent,
                    onChange: (e) => setRawContent(e.target.value),
                    rows: 16,
                    className: "langley-raw-editor",
                    "data-testid": "raw-editor"
                  }
                )
              ] }),
              /* @__PURE__ */ jsxs9("div", { className: "langley-actions", style: { marginTop: 12 }, children: [
                /* @__PURE__ */ jsx10(
                  "button",
                  {
                    className: "langley-btn langley-btn-primary",
                    onClick: handleSaveRaw,
                    "data-testid": "save-raw",
                    children: "Save"
                  }
                ),
                /* @__PURE__ */ jsx10("button", { className: "langley-btn", onClick: cancelEditing, children: "Cancel" })
              ] })
            ]
          }
        ) : /* @__PURE__ */ jsxs9(Fragment5, { children: [
          /* @__PURE__ */ jsxs9("dl", { className: "langley-profile-dl", children: [
            /* @__PURE__ */ jsx10("dt", { children: "ID" }),
            /* @__PURE__ */ jsx10("dd", { children: /* @__PURE__ */ jsx10("code", { children: selected.id }) }),
            /* @__PURE__ */ jsx10("dt", { children: "Tenant" }),
            /* @__PURE__ */ jsx10("dd", { children: selected.tenant_id }),
            /* @__PURE__ */ jsx10("dt", { children: "Version" }),
            /* @__PURE__ */ jsx10("dd", { children: selected.version }),
            /* @__PURE__ */ jsx10("dt", { children: "Provider" }),
            /* @__PURE__ */ jsx10("dd", { children: selected.llm_provider || "\u2014" }),
            /* @__PURE__ */ jsx10("dt", { children: "Model" }),
            /* @__PURE__ */ jsx10("dd", { children: selected.model || "\u2014" }),
            /* @__PURE__ */ jsx10("dt", { children: "Command" }),
            /* @__PURE__ */ jsx10("dd", { children: selected.command.length > 0 ? selected.command.join(" ") : "\u2014" }),
            /* @__PURE__ */ jsx10("dt", { children: "System Prompt" }),
            /* @__PURE__ */ jsx10("dd", { className: "langley-profile-prompt", children: selected.system_prompt || "\u2014" }),
            /* @__PURE__ */ jsx10("dt", { children: "Tags" }),
            /* @__PURE__ */ jsx10("dd", { children: selected.tags?.length > 0 ? selected.tags.join(", ") : "\u2014" })
          ] }),
          /* @__PURE__ */ jsxs9("div", { className: "langley-actions", style: { marginTop: 16 }, children: [
            /* @__PURE__ */ jsx10(
              "button",
              {
                className: "langley-btn langley-btn-primary",
                onClick: () => handleLaunch(selected.id),
                children: "Launch Agent"
              }
            ),
            /* @__PURE__ */ jsx10(
              "button",
              {
                className: "langley-btn",
                onClick: () => startEditing(selected),
                "data-testid": "edit-profile",
                children: "Edit"
              }
            ),
            /* @__PURE__ */ jsx10(
              "button",
              {
                className: "langley-btn",
                onClick: () => startRawEditing(selected),
                "data-testid": "raw-edit-profile",
                children: "Raw JSON"
              }
            ),
            /* @__PURE__ */ jsx10(
              "button",
              {
                className: "langley-btn",
                onClick: () => handleSaveToAgentsDir(selected),
                title: "Save to provider's agents directory",
                "data-testid": "save-to-agents-dir",
                children: "Save to Agents Dir"
              }
            ),
            /* @__PURE__ */ jsx10(
              "button",
              {
                className: "langley-btn",
                onClick: () => handleSaveToDisk(selected),
                title: "Save to a custom file path",
                "data-testid": "save-to-disk",
                children: "Save to Disk"
              }
            ),
            /* @__PURE__ */ jsx10(
              "button",
              {
                className: "langley-btn langley-btn-danger",
                onClick: () => handleDelete(selected.id),
                children: "Delete"
              }
            )
          ] })
        ] }),
        runningAgents.length > 0 && /* @__PURE__ */ jsxs9(
          "div",
          {
            className: "langley-generate-profile",
            style: { marginTop: 16 },
            children: [
              /* @__PURE__ */ jsx10("h3", { children: "Generate Agent Self-Profile" }),
              /* @__PURE__ */ jsx10("p", { className: "langley-profile-meta", children: "Send a running agent a prompt to generate an agentic profile of itself." }),
              /* @__PURE__ */ jsx10("div", { className: "langley-actions", children: runningAgents.map((a) => /* @__PURE__ */ jsxs9(
                "button",
                {
                  className: "langley-btn",
                  onClick: () => handleGenerateProfile(a.agent_id),
                  "data-testid": `generate-profile-${a.agent_id}`,
                  children: [
                    "Generate from ",
                    a.profile_name
                  ]
                },
                a.agent_id
              )) })
            ]
          }
        )
      ] }) : /* @__PURE__ */ jsx10("div", { className: "langley-empty", children: "Select a profile to view details." }) })
    ] })
  ] });
}

// src/ts/components/AgentInspector.tsx
import { useState as useState8, useEffect as useEffect6, useCallback as useCallback7, useRef as useRef4 } from "react";
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
function formatTime2(ts) {
  return new Date(ts * 1e3).toLocaleTimeString();
}
function formatDateTime(ts) {
  return new Date(ts * 1e3).toLocaleString();
}
function formatUptime(seconds) {
  if (seconds < 60) return `${Math.floor(seconds)}s`;
  if (seconds < 3600)
    return `${Math.floor(seconds / 60)}m ${Math.floor(seconds % 60)}s`;
  const h = Math.floor(seconds / 3600);
  const m = Math.floor(seconds % 3600 / 60);
  return `${h}h ${m}m`;
}
function AgentInspector({
  agentId,
  onBack,
  onAction
}) {
  const [agent, setAgent] = useState8(null);
  const [profile, setProfile] = useState8(null);
  const [activeTab, setActiveTab] = useState8("chat");
  const [error, setError] = useState8(null);
  const [chatMessages, setChatMessages] = useState8([]);
  const [chatInput, setChatInput] = useState8("");
  const [sending, setSending] = useState8(false);
  const outboxSeqRef = useRef4(0);
  const inboxSeqRef = useRef4(0);
  const pendingContentRef = useRef4("");
  const chatEndRef = useRef4(null);
  const [logs, setLogs] = useState8([]);
  const logSeqRef = useRef4(0);
  const [messageEntries, setMessageEntries] = useState8([]);
  const msgInSeqRef = useRef4(0);
  const msgOutSeqRef = useRef4(0);
  const [checkpoints, setCheckpoints] = useState8([]);
  const [approvals, setApprovals] = useState8([]);
  useEffect6(() => {
    const fetchAgent = async () => {
      try {
        const info = await getAgent(agentId);
        setAgent(info);
        if (info.profile_id) {
          try {
            const p = await getProfile(info.profile_id);
            setProfile(p);
          } catch {
          }
        }
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to fetch agent");
      }
    };
    fetchAgent();
    const interval = setInterval(fetchAgent, 5e3);
    return () => clearInterval(interval);
  }, [agentId]);
  useEffect6(() => {
    if (activeTab !== "chat") return;
    const poll = async () => {
      try {
        const outboxMsgs = await queryMessages(`agent.${agentId}.outbox`, {
          from_seq: outboxSeqRef.current,
          limit: 50
        });
        const newMsgs = [];
        for (const msg of outboxMsgs) {
          const body = msg.body;
          if (msg.sequence > outboxSeqRef.current)
            outboxSeqRef.current = msg.sequence;
          const type = body.type ?? "";
          if (type === "delta") {
            pendingContentRef.current += body.content ?? "";
          } else if (type === "message" || type === "turn_complete") {
            const content = pendingContentRef.current || body.content || "";
            pendingContentRef.current = "";
            if (content) {
              newMsgs.push({
                id: msg.id,
                role: "assistant",
                content,
                timestamp: msg.timestamp,
                type: "message"
              });
            }
          } else if (type === "tool_start") {
            newMsgs.push({
              id: msg.id,
              role: "system",
              content: `Using tool: ${body.tool_name}`,
              timestamp: msg.timestamp,
              type: "tool"
            });
          } else if (type === "error") {
            newMsgs.push({
              id: msg.id,
              role: "system",
              content: `Error: ${body.message}`,
              timestamp: msg.timestamp,
              type: "error"
            });
          }
        }
        if (newMsgs.length > 0)
          setChatMessages((prev) => [...prev, ...newMsgs]);
        const inboxMsgs = await queryMessages(`agent.${agentId}.inbox`, {
          from_seq: inboxSeqRef.current,
          limit: 50
        });
        for (const msg of inboxMsgs) {
          if (msg.sequence > inboxSeqRef.current)
            inboxSeqRef.current = msg.sequence;
        }
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 1e3);
    return () => clearInterval(interval);
  }, [agentId, activeTab]);
  useEffect6(() => {
    if (activeTab !== "logs") return;
    const poll = async () => {
      try {
        const newLogs = [];
        for (const ch of [
          `agent.${agentId}.outbox`,
          `agent.${agentId}.inbox`
        ]) {
          const msgs = await queryMessages(ch, {
            from_seq: logSeqRef.current,
            limit: 100
          });
          for (const msg of msgs) {
            if (msg.sequence > logSeqRef.current)
              logSeqRef.current = msg.sequence;
            const body = msg.body;
            newLogs.push({
              id: msg.id,
              timestamp: body.timestamp ?? msg.timestamp,
              level: (body.level ?? body.type ?? "info").toLowerCase(),
              message: body.message ?? body.content ?? JSON.stringify(body)
            });
          }
        }
        if (newLogs.length > 0) setLogs((prev) => [...prev, ...newLogs]);
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 2e3);
    return () => clearInterval(interval);
  }, [agentId, activeTab]);
  useEffect6(() => {
    if (activeTab !== "messages") return;
    const poll = async () => {
      try {
        const entries = [];
        const inboxMsgs = await queryMessages(`agent.${agentId}.inbox`, {
          from_seq: msgInSeqRef.current,
          limit: 100
        });
        for (const msg of inboxMsgs) {
          if (msg.sequence > msgInSeqRef.current)
            msgInSeqRef.current = msg.sequence;
          const body = msg.body;
          entries.push({
            id: msg.id,
            timestamp: msg.timestamp,
            channel: msg.channel,
            direction: "in",
            body: body.text ?? body.content ?? JSON.stringify(body)
          });
        }
        const outboxMsgs = await queryMessages(`agent.${agentId}.outbox`, {
          from_seq: msgOutSeqRef.current,
          limit: 100
        });
        for (const msg of outboxMsgs) {
          if (msg.sequence > msgOutSeqRef.current)
            msgOutSeqRef.current = msg.sequence;
          const body = msg.body;
          entries.push({
            id: msg.id,
            timestamp: msg.timestamp,
            channel: msg.channel,
            direction: "out",
            body: body.text ?? body.content ?? JSON.stringify(body)
          });
        }
        if (entries.length > 0) {
          entries.sort((a, b) => a.timestamp - b.timestamp);
          setMessageEntries((prev) => [...prev, ...entries]);
        }
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 2e3);
    return () => clearInterval(interval);
  }, [agentId, activeTab]);
  useEffect6(() => {
    if (activeTab !== "checkpoints") return;
    const fetch2 = async () => {
      try {
        const cps = await listCheckpoints(agentId);
        setCheckpoints(cps);
      } catch {
      }
    };
    fetch2();
    const interval = setInterval(fetch2, 1e4);
    return () => clearInterval(interval);
  }, [agentId, activeTab]);
  useEffect6(() => {
    if (activeTab !== "approvals") return;
    const fetch2 = async () => {
      try {
        const entries = await queryAudit("default", {
          agent_id: agentId,
          event_type: "approval_requested",
          limit: 100
        });
        setApprovals(entries);
      } catch {
      }
    };
    fetch2();
    const interval = setInterval(fetch2, 5e3);
    return () => clearInterval(interval);
  }, [agentId, activeTab]);
  useEffect6(() => {
    chatEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [chatMessages]);
  const handleSendChat = useCallback7(async () => {
    const text = chatInput.trim();
    if (!text || sending) return;
    setSending(true);
    setChatInput("");
    setChatMessages((prev) => [
      ...prev,
      {
        id: `user-${Date.now()}`,
        role: "user",
        content: text,
        timestamp: Date.now() / 1e3
      }
    ]);
    try {
      await sendMessageToAgent(agentId, { text });
    } catch {
      setChatMessages((prev) => [
        ...prev,
        {
          id: `err-${Date.now()}`,
          role: "system",
          content: "Failed to send message",
          timestamp: Date.now() / 1e3,
          type: "error"
        }
      ]);
    } finally {
      setSending(false);
    }
  }, [agentId, chatInput, sending]);
  const handleAction = useCallback7(
    async (action) => {
      try {
        if (action === "stop") await stopAgent(agentId);
        else if (action === "kill") await killAgent(agentId);
        else if (action === "restart") await restartAgent(agentId);
        onAction?.(agentId, action);
      } catch (err) {
        setError(err instanceof Error ? err.message : `Failed to ${action}`);
      }
    },
    [agentId, onAction]
  );
  const tabs = [
    { id: "chat", label: "Chat" },
    { id: "logs", label: "Logs" },
    { id: "messages", label: "Messages" },
    { id: "checkpoints", label: "Checkpoints" },
    { id: "profile", label: "Profile" },
    { id: "approvals", label: "Approvals" }
  ];
  return /* @__PURE__ */ jsxs10("div", { className: "langley-inspector", "data-testid": "agent-inspector", children: [
    /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-header", children: [
      /* @__PURE__ */ jsx11(
        "button",
        {
          className: "langley-btn",
          onClick: onBack,
          "data-testid": "inspector-back",
          children: "\u2190 Back"
        }
      ),
      /* @__PURE__ */ jsx11("h2", { children: agent?.profile_name ?? agentId }),
      agent && /* @__PURE__ */ jsx11(
        StatusBadge,
        {
          status: agent.status
        }
      ),
      agent?.status === "running" && /* @__PURE__ */ jsxs10("div", { className: "langley-actions", children: [
        /* @__PURE__ */ jsx11(
          "button",
          {
            className: "langley-btn",
            onClick: () => handleAction("stop"),
            children: "Stop"
          }
        ),
        /* @__PURE__ */ jsx11(
          "button",
          {
            className: "langley-btn langley-btn-danger",
            onClick: () => handleAction("kill"),
            children: "Kill"
          }
        ),
        /* @__PURE__ */ jsx11(
          "button",
          {
            className: "langley-btn",
            onClick: () => handleAction("restart"),
            children: "Restart"
          }
        )
      ] })
    ] }),
    error && /* @__PURE__ */ jsxs10("div", { className: "langley-error", children: [
      error,
      /* @__PURE__ */ jsx11(
        "button",
        {
          className: "langley-btn",
          onClick: () => setError(null),
          style: { marginLeft: 8 },
          children: "Dismiss"
        }
      )
    ] }),
    agent && /* @__PURE__ */ jsxs10(
      "div",
      {
        className: "langley-inspector-status",
        "data-testid": "inspector-status",
        children: [
          /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "Status" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: agent.status })
          ] }),
          /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "Uptime" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: formatUptime(agent.uptime_seconds) })
          ] }),
          /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "PID" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: agent.pid ?? "\u2014" })
          ] }),
          /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "Restarts" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: agent.restart_count })
          ] }),
          /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "Restart Policy" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: agent.restart_policy })
          ] }),
          /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "Last Heartbeat" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: agent.last_heartbeat ? formatTime2(agent.last_heartbeat) : "\u2014" })
          ] }),
          agent.error_message && /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-stat langley-inspector-stat-error", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-label", children: "Error" }),
            /* @__PURE__ */ jsx11("span", { className: "langley-inspector-stat-value", children: agent.error_message })
          ] })
        ]
      }
    ),
    /* @__PURE__ */ jsx11("nav", { className: "langley-inspector-tabs", "data-testid": "inspector-tabs", children: tabs.map(({ id, label }) => /* @__PURE__ */ jsx11(
      "button",
      {
        className: `langley-inspector-tab${activeTab === id ? " active" : ""}`,
        onClick: () => setActiveTab(id),
        "data-testid": `inspector-tab-${id}`,
        children: label
      },
      id
    )) }),
    /* @__PURE__ */ jsxs10(
      "div",
      {
        className: "langley-inspector-content",
        "data-testid": "inspector-content",
        children: [
          activeTab === "chat" && /* @__PURE__ */ jsxs10("div", { className: "langley-inspector-chat", children: [
            /* @__PURE__ */ jsxs10("div", { className: "langley-chat-messages", children: [
              chatMessages.length === 0 && /* @__PURE__ */ jsx11("div", { className: "langley-empty", children: "No messages yet. Send a message to start chatting." }),
              chatMessages.map((msg) => /* @__PURE__ */ jsxs10(
                "div",
                {
                  className: `langley-chat-message langley-chat-${msg.role}`,
                  children: [
                    /* @__PURE__ */ jsx11("span", { className: "langley-chat-role", children: msg.role }),
                    /* @__PURE__ */ jsx11("span", { className: "langley-chat-content", children: msg.content }),
                    /* @__PURE__ */ jsx11("span", { className: "langley-chat-time", children: formatTime2(msg.timestamp) })
                  ]
                },
                msg.id
              )),
              /* @__PURE__ */ jsx11("div", { ref: chatEndRef })
            ] }),
            /* @__PURE__ */ jsxs10("div", { className: "langley-chat-input-bar", children: [
              /* @__PURE__ */ jsx11(
                "input",
                {
                  type: "text",
                  value: chatInput,
                  onChange: (e) => setChatInput(e.target.value),
                  onKeyDown: (e) => e.key === "Enter" && handleSendChat(),
                  placeholder: "Send a message...",
                  className: "langley-chat-input",
                  disabled: agent?.status !== "running",
                  "data-testid": "inspector-chat-input"
                }
              ),
              /* @__PURE__ */ jsx11(
                "button",
                {
                  className: "langley-btn langley-btn-primary",
                  onClick: handleSendChat,
                  disabled: !chatInput.trim() || sending || agent?.status !== "running",
                  "data-testid": "inspector-chat-send",
                  children: "Send"
                }
              )
            ] })
          ] }),
          activeTab === "logs" && /* @__PURE__ */ jsx11("div", { className: "langley-inspector-logs", children: logs.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "langley-empty", children: "No log entries yet." }) : logs.map((entry) => /* @__PURE__ */ jsxs10(
            "div",
            {
              className: `langley-log-entry langley-log-${entry.level}`,
              children: [
                /* @__PURE__ */ jsx11("span", { className: "langley-log-time", children: formatTime2(entry.timestamp) }),
                /* @__PURE__ */ jsx11("span", { className: "langley-log-level", children: entry.level }),
                /* @__PURE__ */ jsx11("span", { className: "langley-log-message", children: entry.message })
              ]
            },
            entry.id
          )) }),
          activeTab === "messages" && /* @__PURE__ */ jsx11("div", { className: "langley-inspector-messages", children: messageEntries.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "langley-empty", children: "No messages yet." }) : messageEntries.map((entry) => /* @__PURE__ */ jsxs10(
            "div",
            {
              className: `langley-log-entry langley-msg-${entry.direction}`,
              children: [
                /* @__PURE__ */ jsx11("span", { className: "langley-log-time", children: formatTime2(entry.timestamp) }),
                /* @__PURE__ */ jsx11("span", { className: "langley-log-level", children: entry.direction === "in" ? "\u2190 IN" : "\u2192 OUT" }),
                /* @__PURE__ */ jsx11("span", { className: "langley-log-message", children: entry.body })
              ]
            },
            entry.id
          )) }),
          activeTab === "checkpoints" && /* @__PURE__ */ jsx11("div", { className: "langley-inspector-checkpoints", children: checkpoints.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "langley-empty", children: "No checkpoints saved for this agent." }) : /* @__PURE__ */ jsxs10("table", { className: "langley-agent-table", children: [
            /* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
              /* @__PURE__ */ jsx11("th", { children: "Sequence" }),
              /* @__PURE__ */ jsx11("th", { children: "Timestamp" }),
              /* @__PURE__ */ jsx11("th", { children: "Machine" }),
              /* @__PURE__ */ jsx11("th", { children: "Metadata" })
            ] }) }),
            /* @__PURE__ */ jsx11("tbody", { children: checkpoints.map((cp) => /* @__PURE__ */ jsxs10("tr", { children: [
              /* @__PURE__ */ jsx11("td", { children: cp.sequence }),
              /* @__PURE__ */ jsx11("td", { children: formatDateTime(cp.timestamp) }),
              /* @__PURE__ */ jsx11("td", { children: cp.machine_id || "\u2014" }),
              /* @__PURE__ */ jsx11("td", { children: /* @__PURE__ */ jsx11("code", { children: JSON.stringify(cp.metadata) }) })
            ] }, cp.id)) })
          ] }) }),
          activeTab === "profile" && /* @__PURE__ */ jsx11("div", { className: "langley-inspector-profile", children: profile ? /* @__PURE__ */ jsxs10("dl", { className: "langley-profile-dl", children: [
            /* @__PURE__ */ jsx11("dt", { children: "Profile ID" }),
            /* @__PURE__ */ jsx11("dd", { children: /* @__PURE__ */ jsx11("code", { children: profile.id }) }),
            /* @__PURE__ */ jsx11("dt", { children: "Name" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.name }),
            /* @__PURE__ */ jsx11("dt", { children: "Version" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.version }),
            /* @__PURE__ */ jsx11("dt", { children: "Tenant" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.tenant_id }),
            /* @__PURE__ */ jsx11("dt", { children: "Provider" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.llm_provider || "\u2014" }),
            /* @__PURE__ */ jsx11("dt", { children: "Model" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.model || "\u2014" }),
            /* @__PURE__ */ jsx11("dt", { children: "Command" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.command.length > 0 ? profile.command.join(" ") : "\u2014" }),
            /* @__PURE__ */ jsx11("dt", { children: "System Prompt" }),
            /* @__PURE__ */ jsx11("dd", { className: "langley-profile-prompt", children: profile.system_prompt || "\u2014" }),
            /* @__PURE__ */ jsx11("dt", { children: "Tags" }),
            /* @__PURE__ */ jsx11("dd", { children: profile.tags?.length > 0 ? profile.tags.join(", ") : "\u2014" })
          ] }) : /* @__PURE__ */ jsx11("div", { className: "langley-empty", children: "Profile not available." }) }),
          activeTab === "approvals" && /* @__PURE__ */ jsx11("div", { className: "langley-inspector-approvals", children: approvals.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "langley-empty", children: "No approval requests." }) : approvals.map((entry) => /* @__PURE__ */ jsxs10("div", { className: "langley-approval-entry", children: [
            /* @__PURE__ */ jsx11("span", { className: "langley-log-time", children: formatTime2(entry.timestamp) }),
            /* @__PURE__ */ jsx11("span", { className: "langley-approval-desc", children: entry.payload.description ?? entry.event_type }),
            /* @__PURE__ */ jsx11("span", { className: "langley-approval-status", children: entry.payload.status ?? "pending" })
          ] }, entry.id)) })
        ]
      }
    )
  ] });
}

// src/ts/components/MessageInspectorTab.tsx
import { useState as useState9, useEffect as useEffect7, useCallback as useCallback8, useRef as useRef5 } from "react";
import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
function formatTime3(ts) {
  return new Date(ts * 1e3).toLocaleTimeString();
}
function MessageInspectorTab() {
  const [channels, setChannels] = useState9([]);
  const [selectedChannel, setSelectedChannel] = useState9("");
  const [messages, setMessages] = useState9([]);
  const [search, setSearch] = useState9("");
  const [expandedMsg, setExpandedMsg] = useState9(null);
  const [error, setError] = useState9(null);
  const [replayTarget, setReplayTarget] = useState9("");
  const [replayFeedback, setReplayFeedback] = useState9(null);
  const seqRef = useRef5(0);
  const messagesEndRef = useRef5(null);
  const [autoScroll, setAutoScroll] = useState9(true);
  const refreshChannels = useCallback8(async () => {
    try {
      const chs = await listChannels();
      setChannels(chs);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to load channels");
    }
  }, []);
  useEffect7(() => {
    refreshChannels();
    const interval = setInterval(refreshChannels, 1e4);
    return () => clearInterval(interval);
  }, [refreshChannels]);
  useEffect7(() => {
    setMessages([]);
    seqRef.current = 0;
  }, [selectedChannel]);
  useEffect7(() => {
    if (!selectedChannel) return;
    const poll = async () => {
      try {
        const msgs = await queryMessages(selectedChannel, {
          from_seq: seqRef.current,
          limit: 100
        });
        if (msgs.length > 0) {
          for (const msg of msgs) {
            if (msg.sequence > seqRef.current) seqRef.current = msg.sequence;
          }
          setMessages((prev) => [...prev, ...msgs]);
        }
      } catch {
      }
    };
    poll();
    const interval = setInterval(poll, 2e3);
    return () => clearInterval(interval);
  }, [selectedChannel]);
  useEffect7(() => {
    if (autoScroll) {
      messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
    }
  }, [messages, autoScroll]);
  const handleReplay = useCallback8(
    async (msgId) => {
      if (!replayTarget) return;
      try {
        await replayMessage(selectedChannel, msgId, replayTarget);
        setReplayFeedback(`Message replayed to ${replayTarget}`);
        setTimeout(() => setReplayFeedback(null), 3e3);
      } catch (err) {
        setError(err instanceof Error ? err.message : "Replay failed");
      }
    },
    [selectedChannel, replayTarget]
  );
  const filteredMessages = messages.filter((msg) => {
    if (!search) return true;
    const s = search.toLowerCase();
    const bodyStr = typeof msg.body === "string" ? msg.body : JSON.stringify(msg.body);
    return bodyStr.toLowerCase().includes(s) || msg.sender.toLowerCase().includes(s) || msg.recipient.toLowerCase().includes(s) || msg.id.toLowerCase().includes(s);
  });
  return /* @__PURE__ */ jsx12("div", { className: "langley-message-inspector", "data-testid": "message-inspector", children: /* @__PURE__ */ jsxs11("div", { className: "langley-message-inspector-layout", children: [
    /* @__PURE__ */ jsxs11("div", { className: "langley-channel-list", "data-testid": "channel-list", children: [
      /* @__PURE__ */ jsx12("h3", { children: "Channels" }),
      /* @__PURE__ */ jsx12(
        "button",
        {
          className: "langley-btn",
          onClick: refreshChannels,
          style: { marginBottom: 8 },
          children: "Refresh"
        }
      ),
      channels.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "langley-empty", children: "No channels found." }) : /* @__PURE__ */ jsx12("ul", { className: "langley-channel-items", children: channels.map((ch) => /* @__PURE__ */ jsx12(
        "li",
        {
          className: `langley-channel-item${selectedChannel === ch.channel ? " active" : ""}`,
          children: /* @__PURE__ */ jsxs11(
            "button",
            {
              className: "langley-channel-select",
              onClick: () => setSelectedChannel(ch.channel),
              children: [
                /* @__PURE__ */ jsx12("span", { className: "langley-channel-name", children: ch.channel }),
                /* @__PURE__ */ jsxs11("span", { className: "langley-channel-count", children: [
                  ch.message_count,
                  " msgs"
                ] })
              ]
            }
          )
        },
        ch.channel
      )) })
    ] }),
    /* @__PURE__ */ jsxs11("div", { className: "langley-channel-detail", "data-testid": "channel-detail", children: [
      error && /* @__PURE__ */ jsxs11("div", { className: "langley-error", children: [
        error,
        /* @__PURE__ */ jsx12(
          "button",
          {
            className: "langley-btn",
            onClick: () => setError(null),
            style: { marginLeft: 8 },
            children: "Dismiss"
          }
        )
      ] }),
      replayFeedback && /* @__PURE__ */ jsx12("div", { className: "langley-save-feedback", children: replayFeedback }),
      !selectedChannel ? /* @__PURE__ */ jsx12("div", { className: "langley-empty", children: "Select a channel to view messages." }) : /* @__PURE__ */ jsxs11(Fragment6, { children: [
        /* @__PURE__ */ jsxs11("div", { className: "langley-message-controls", children: [
          /* @__PURE__ */ jsx12("h3", { children: selectedChannel }),
          /* @__PURE__ */ jsx12(
            "input",
            {
              type: "text",
              value: search,
              onChange: (e) => setSearch(e.target.value),
              placeholder: "Search messages...",
              className: "langley-logs-search",
              "data-testid": "message-search"
            }
          ),
          /* @__PURE__ */ jsxs11("label", { className: "langley-logs-autoscroll", children: [
            /* @__PURE__ */ jsx12(
              "input",
              {
                type: "checkbox",
                checked: autoScroll,
                onChange: (e) => setAutoScroll(e.target.checked)
              }
            ),
            "Auto-scroll"
          ] })
        ] }),
        /* @__PURE__ */ jsxs11(
          "div",
          {
            className: "langley-message-stream",
            "data-testid": "message-stream",
            children: [
              filteredMessages.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "langley-empty", children: "No messages in this channel." }) : filteredMessages.map((msg) => /* @__PURE__ */ jsxs11(
                "div",
                {
                  className: `langley-message-entry${expandedMsg === msg.id ? " expanded" : ""}`,
                  "data-testid": `message-${msg.id}`,
                  children: [
                    /* @__PURE__ */ jsxs11(
                      "div",
                      {
                        className: "langley-message-summary",
                        onClick: () => setExpandedMsg(expandedMsg === msg.id ? null : msg.id),
                        children: [
                          /* @__PURE__ */ jsx12("span", { className: "langley-log-time", children: formatTime3(msg.timestamp) }),
                          /* @__PURE__ */ jsxs11("span", { className: "langley-message-seq", children: [
                            "#",
                            msg.sequence
                          ] }),
                          /* @__PURE__ */ jsx12("span", { className: "langley-message-sender", children: msg.sender || "\u2014" }),
                          /* @__PURE__ */ jsx12("span", { className: "langley-message-arrow", children: "\u2192" }),
                          /* @__PURE__ */ jsx12("span", { className: "langley-message-recipient", children: msg.recipient || "\u2014" }),
                          /* @__PURE__ */ jsx12("span", { className: "langley-message-preview", children: typeof msg.body === "string" ? msg.body.slice(0, 80) : JSON.stringify(msg.body).slice(0, 80) })
                        ]
                      }
                    ),
                    expandedMsg === msg.id && /* @__PURE__ */ jsxs11("div", { className: "langley-message-detail", children: [
                      /* @__PURE__ */ jsxs11("dl", { className: "langley-profile-dl", children: [
                        /* @__PURE__ */ jsx12("dt", { children: "Message ID" }),
                        /* @__PURE__ */ jsx12("dd", { children: /* @__PURE__ */ jsx12("code", { children: msg.id }) }),
                        /* @__PURE__ */ jsx12("dt", { children: "Sequence" }),
                        /* @__PURE__ */ jsx12("dd", { children: msg.sequence }),
                        /* @__PURE__ */ jsx12("dt", { children: "Sender" }),
                        /* @__PURE__ */ jsx12("dd", { children: msg.sender || "\u2014" }),
                        /* @__PURE__ */ jsx12("dt", { children: "Recipient" }),
                        /* @__PURE__ */ jsx12("dd", { children: msg.recipient || "\u2014" }),
                        /* @__PURE__ */ jsx12("dt", { children: "Channel" }),
                        /* @__PURE__ */ jsx12("dd", { children: msg.channel }),
                        /* @__PURE__ */ jsx12("dt", { children: "Timestamp" }),
                        /* @__PURE__ */ jsx12("dd", { children: new Date(msg.timestamp * 1e3).toISOString() }),
                        /* @__PURE__ */ jsx12("dt", { children: "Body" }),
                        /* @__PURE__ */ jsx12("dd", { children: /* @__PURE__ */ jsx12("pre", { className: "langley-message-body-pre", children: typeof msg.body === "string" ? msg.body : JSON.stringify(msg.body, null, 2) }) })
                      ] }),
                      /* @__PURE__ */ jsxs11("div", { className: "langley-message-replay-bar", children: [
                        /* @__PURE__ */ jsx12(
                          "input",
                          {
                            type: "text",
                            value: replayTarget,
                            onChange: (e) => setReplayTarget(e.target.value),
                            placeholder: "Target channel for replay...",
                            className: "langley-logs-search"
                          }
                        ),
                        /* @__PURE__ */ jsx12(
                          "button",
                          {
                            className: "langley-btn",
                            disabled: !replayTarget,
                            onClick: () => handleReplay(msg.id),
                            children: "Replay"
                          }
                        )
                      ] })
                    ] })
                  ]
                },
                msg.id
              )),
              /* @__PURE__ */ jsx12("div", { ref: messagesEndRef })
            ]
          }
        )
      ] })
    ] })
  ] }) });
}

// src/ts/components/TraceTab.tsx
import { useState as useState10, useEffect as useEffect8, useCallback as useCallback9 } from "react";
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
function formatDateTime2(ts) {
  return new Date(ts * 1e3).toLocaleString();
}
var EVENT_TYPE_COLORS = {
  "agent.started": "var(--green)",
  "agent.stopped": "var(--gray)",
  "agent.killed": "var(--red)",
  "agent.exited": "var(--gray)",
  "agent.errored": "var(--red)",
  "agent.auto_restarted": "var(--yellow)",
  "agent.heartbeat_timeout": "var(--red)",
  "agent.launch_failed": "var(--red)",
  "agent.stop_requested": "var(--yellow)",
  "agent.force_killed_after_timeout": "var(--red)"
};
function TraceTab({ agents }) {
  const [selectedAgent, setSelectedAgent] = useState10("");
  const [eventFilter, setEventFilter] = useState10("all");
  const [operations, setOperations] = useState10([]);
  const [search, setSearch] = useState10("");
  const [loading, setLoading] = useState10(false);
  const agentNameMap = {};
  for (const a of agents) {
    agentNameMap[a.id] = a.name;
  }
  const fetchOperations = useCallback9(async () => {
    setLoading(true);
    try {
      const opts = { limit: 500 };
      if (selectedAgent) opts.agent_id = selectedAgent;
      if (eventFilter !== "all") opts.event_type = eventFilter;
      const entries = await queryAudit("default", opts);
      setOperations(
        entries.map((e) => ({
          id: e.id,
          agent_id: e.agent_id,
          agent_name: agentNameMap[e.agent_id] ?? e.agent_id?.slice(0, 8) ?? "unknown",
          event_type: e.event_type,
          timestamp: e.timestamp,
          payload: e.payload
        }))
      );
    } catch {
    }
    setLoading(false);
  }, [selectedAgent, eventFilter]);
  useEffect8(() => {
    fetchOperations();
    const interval = setInterval(fetchOperations, 5e3);
    return () => clearInterval(interval);
  }, [fetchOperations]);
  const stats = {
    total: operations.length,
    launches: operations.filter((o) => o.event_type === "agent.started").length,
    errors: operations.filter(
      (o) => o.event_type.includes("error") || o.event_type.includes("failed") || o.event_type.includes("killed")
    ).length,
    restarts: operations.filter((o) => o.event_type === "agent.auto_restarted").length
  };
  const filteredOps = operations.filter((o) => {
    if (!search) return true;
    const s = search.toLowerCase();
    return o.event_type.toLowerCase().includes(s) || o.agent_name.toLowerCase().includes(s) || o.agent_id.toLowerCase().includes(s) || JSON.stringify(o.payload).toLowerCase().includes(s);
  });
  const eventTypes = [...new Set(operations.map((o) => o.event_type))].sort();
  return /* @__PURE__ */ jsxs12("div", { className: "langley-trace-tab", "data-testid": "trace-tab", children: [
    /* @__PURE__ */ jsxs12("div", { className: "langley-trace-stats", children: [
      /* @__PURE__ */ jsxs12("div", { className: "langley-trace-stat-card", children: [
        /* @__PURE__ */ jsx13("span", { className: "langley-trace-stat-value", children: stats.total }),
        /* @__PURE__ */ jsx13("span", { className: "langley-trace-stat-label", children: "Total Events" })
      ] }),
      /* @__PURE__ */ jsxs12("div", { className: "langley-trace-stat-card", children: [
        /* @__PURE__ */ jsx13(
          "span",
          {
            className: "langley-trace-stat-value",
            style: { color: "var(--green)" },
            children: stats.launches
          }
        ),
        /* @__PURE__ */ jsx13("span", { className: "langley-trace-stat-label", children: "Launches" })
      ] }),
      /* @__PURE__ */ jsxs12("div", { className: "langley-trace-stat-card", children: [
        /* @__PURE__ */ jsx13(
          "span",
          {
            className: "langley-trace-stat-value",
            style: { color: "var(--red)" },
            children: stats.errors
          }
        ),
        /* @__PURE__ */ jsx13("span", { className: "langley-trace-stat-label", children: "Errors/Kills" })
      ] }),
      /* @__PURE__ */ jsxs12("div", { className: "langley-trace-stat-card", children: [
        /* @__PURE__ */ jsx13(
          "span",
          {
            className: "langley-trace-stat-value",
            style: { color: "var(--yellow)" },
            children: stats.restarts
          }
        ),
        /* @__PURE__ */ jsx13("span", { className: "langley-trace-stat-label", children: "Auto-Restarts" })
      ] })
    ] }),
    /* @__PURE__ */ jsxs12("div", { className: "langley-logs-controls", children: [
      /* @__PURE__ */ jsx13("label", { htmlFor: "trace-agent-select", children: "Agent: " }),
      /* @__PURE__ */ jsxs12(
        "select",
        {
          id: "trace-agent-select",
          value: selectedAgent,
          onChange: (e) => setSelectedAgent(e.target.value),
          "data-testid": "trace-agent-select",
          children: [
            /* @__PURE__ */ jsx13("option", { value: "", children: "All Agents" }),
            agents.map((a) => /* @__PURE__ */ jsxs12("option", { value: a.id, children: [
              a.name,
              " (",
              a.id.slice(0, 8),
              ")"
            ] }, a.id))
          ]
        }
      ),
      /* @__PURE__ */ jsx13("label", { htmlFor: "trace-event-filter", children: "Event: " }),
      /* @__PURE__ */ jsxs12(
        "select",
        {
          id: "trace-event-filter",
          value: eventFilter,
          onChange: (e) => setEventFilter(e.target.value),
          "data-testid": "trace-event-filter",
          children: [
            /* @__PURE__ */ jsx13("option", { value: "all", children: "All Events" }),
            eventTypes.map((t) => /* @__PURE__ */ jsx13("option", { value: t, children: t }, t))
          ]
        }
      ),
      /* @__PURE__ */ jsx13(
        "input",
        {
          type: "text",
          value: search,
          onChange: (e) => setSearch(e.target.value),
          placeholder: "Search events...",
          className: "langley-logs-search",
          "data-testid": "trace-search"
        }
      )
    ] }),
    /* @__PURE__ */ jsx13("div", { className: "langley-trace-timeline", "data-testid": "trace-timeline", children: loading && operations.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "langley-empty", children: "Loading..." }) : filteredOps.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "langley-empty", children: "No events found." }) : filteredOps.map((op) => /* @__PURE__ */ jsxs12(
      "div",
      {
        className: "langley-trace-entry",
        "data-testid": `trace-${op.id}`,
        children: [
          /* @__PURE__ */ jsx13(
            "div",
            {
              className: "langley-trace-dot",
              style: {
                backgroundColor: EVENT_TYPE_COLORS[op.event_type] ?? "var(--text-muted)"
              }
            }
          ),
          /* @__PURE__ */ jsxs12("div", { className: "langley-trace-content", children: [
            /* @__PURE__ */ jsxs12("div", { className: "langley-trace-header", children: [
              /* @__PURE__ */ jsx13("span", { className: "langley-trace-time", children: formatDateTime2(op.timestamp) }),
              /* @__PURE__ */ jsx13("span", { className: "langley-trace-event-type", children: op.event_type }),
              /* @__PURE__ */ jsx13("span", { className: "langley-trace-agent", children: op.agent_name })
            ] }),
            Object.keys(op.payload).length > 0 && /* @__PURE__ */ jsx13("div", { className: "langley-trace-payload", children: Object.entries(op.payload).map(([k, v]) => /* @__PURE__ */ jsxs12("span", { className: "langley-trace-kv", children: [
              /* @__PURE__ */ jsxs12("strong", { children: [
                k,
                ":"
              ] }),
              " ",
              typeof v === "string" ? v : JSON.stringify(v)
            ] }, k)) })
          ] })
        ]
      },
      op.id
    )) })
  ] });
}

// src/ts/App.tsx
import "regular-layout";
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
function toSummary(info) {
  const now = Date.now() / 1e3;
  return {
    id: info.agent_id,
    name: info.profile_name,
    status: info.status,
    profile: info.profile_name,
    tenant_id: info.tenant_id,
    uptime_seconds: info.started_at ? now - info.started_at : 0
  };
}
var ALL_PANELS = [
  "status",
  "chat",
  "logs",
  "messages",
  "traces",
  "profiles"
];
function extractPanelNames(layout) {
  const names = /* @__PURE__ */ new Set();
  function walk(node) {
    if (!node || typeof node !== "object") return;
    const n = node;
    if (n.type === "child-panel" && Array.isArray(n.child)) {
      for (const t of n.child) names.add(t);
    } else if (n.type === "split-panel" && Array.isArray(n.children)) {
      for (const c of n.children) walk(c);
    }
  }
  walk(layout);
  return names;
}
function parseHash(hash) {
  const cleaned = hash.replace(/^#\/?/, "");
  const segments = cleaned.split("/").filter(Boolean);
  if (segments[0] === "agent" && segments[1]) {
    return { panels: ["status"], inspector: { agentId: segments[1] } };
  }
  if (segments[0] === "chat") {
    return { panels: ["chat"], chatAgentId: segments[1] };
  }
  const panel = ALL_PANELS.find((p) => p === segments[0]);
  return { panels: panel ? [panel] : ["status"] };
}
function useHash() {
  const [route, setRoute] = useState11(() => parseHash(window.location.hash));
  useEffect9(() => {
    const handler = () => setRoute(parseHash(window.location.hash));
    window.addEventListener("hashchange", handler);
    return () => window.removeEventListener("hashchange", handler);
  }, []);
  return route;
}
function useTheme() {
  const [theme, setTheme] = useState11(() => {
    try {
      return localStorage.getItem("langley-theme") ?? "dark";
    } catch {
      return "dark";
    }
  });
  useEffect9(() => {
    document.documentElement.setAttribute("data-theme", theme);
    try {
      localStorage.setItem("langley-theme", theme);
    } catch {
    }
  }, [theme]);
  const toggle = useCallback10(() => {
    setTheme((t) => t === "dark" ? "light" : "dark");
  }, []);
  return [theme, toggle];
}
var PANEL_LABELS = [
  { id: "status", label: "Status" },
  { id: "chat", label: "Chat" },
  { id: "logs", label: "Logs" },
  { id: "messages", label: "Messages" },
  { id: "traces", label: "Traces" },
  { id: "profiles", label: "Profiles" }
];
function App() {
  const initialRoute = useHash();
  const [theme, toggleTheme] = useTheme();
  const [state, setState] = useState11({
    agents: [],
    connected: false,
    error: null
  });
  const [activity, setActivity] = useState11([]);
  const wsRef = useRef6(null);
  const layoutRef = useRef6(null);
  const [activePanels, setActivePanels] = useState11(
    () => new Set(initialRoute.panels)
  );
  const [inspector, setInspector] = useState11(
    initialRoute.inspector
  );
  const [chatInitialAgent, setChatInitialAgent] = useState11(
    initialRoute.chatAgentId
  );
  const layoutInitedRef = useRef6(false);
  useEffect9(() => {
    const el = layoutRef.current;
    if (!el) return;
    const handler = (e) => {
      const names = extractPanelNames(e.detail);
      setActivePanels(names);
      try {
        localStorage.setItem("langley-layout", JSON.stringify(e.detail));
      } catch {
      }
      if (names.size === 0) {
        el.insertPanel("status");
      }
    };
    el.addEventListener("regular-layout-update", handler);
    if (!layoutInitedRef.current) {
      layoutInitedRef.current = true;
      let restored = false;
      try {
        const saved = localStorage.getItem("langley-layout");
        if (saved) {
          const parsed = JSON.parse(saved);
          el.restore(parsed);
          restored = true;
        }
      } catch {
      }
      if (!restored) {
        for (const p of initialRoute.panels) {
          el.insertPanel(p);
        }
      }
    }
    return () => {
      el.removeEventListener("regular-layout-update", handler);
    };
  }, []);
  const togglePanel = useCallback10(
    (id) => {
      const el = layoutRef.current;
      if (!el) return;
      if (activePanels.has(id)) {
        el.removePanel(id);
      } else {
        el.insertPanel(id);
      }
    },
    [activePanels]
  );
  const fetchAgents = useCallback10(async () => {
    try {
      const data = await listAgents();
      setState((prev) => ({
        ...prev,
        agents: data.map(toSummary),
        error: null
      }));
    } catch (err) {
      setState((prev) => ({
        ...prev,
        error: err instanceof Error ? err.message : "Failed to fetch agents"
      }));
    }
  }, []);
  const refreshActivity = useCallback10(async () => {
    try {
      const events = await fetchActivity(30);
      setActivity(events);
    } catch {
    }
  }, []);
  const onAgentsChanged = useCallback10(() => {
    fetchAgents();
    refreshActivity();
  }, [fetchAgents, refreshActivity]);
  useEffect9(() => {
    fetchAgents();
    refreshActivity();
    const interval = setInterval(() => {
      fetchAgents();
      refreshActivity();
    }, 5e3);
    const ws = new LangleyWsClient();
    wsRef.current = ws;
    ws.onConnect = () => setState((prev) => ({ ...prev, connected: true }));
    ws.onDisconnect = () => setState((prev) => ({ ...prev, connected: false }));
    ws.onError = (msg) => setState((prev) => ({ ...prev, error: msg }));
    ws.subscribe("agent.status", () => {
      fetchAgents();
      refreshActivity();
    });
    ws.connect();
    return () => {
      clearInterval(interval);
      ws.disconnect();
    };
  }, [fetchAgents, refreshActivity]);
  const handleNavigateChat = useCallback10(
    (agentId) => {
      setChatInitialAgent(agentId);
      const el = layoutRef.current;
      if (el && !activePanels.has("chat")) {
        el.insertPanel("chat");
      }
    },
    [activePanels]
  );
  const handleNavigateInspect = useCallback10((agentId) => {
    setInspector({ agentId });
  }, []);
  const handleBulkAction = useCallback10(
    async (agentIds, action) => {
      for (const id of agentIds) {
        try {
          if (action === "stop") await stopAgent(id);
          else if (action === "kill") await killAgent(id);
          else if (action === "restart") await restartAgent(id);
        } catch {
        }
      }
      onAgentsChanged();
    },
    [onAgentsChanged]
  );
  return /* @__PURE__ */ jsxs13("div", { className: "langley-app", "data-testid": "langley-app", children: [
    /* @__PURE__ */ jsxs13("header", { className: "langley-header", children: [
      /* @__PURE__ */ jsx14("h1", { children: "Langley" }),
      /* @__PURE__ */ jsx14("nav", { className: "langley-nav", "data-testid": "tab-nav", children: PANEL_LABELS.map(({ id, label }) => /* @__PURE__ */ jsx14(
        "button",
        {
          className: `langley-nav-tab${activePanels.has(id) ? " active" : ""}`,
          "data-testid": `tab-${id}`,
          onClick: () => togglePanel(id),
          children: label
        },
        id
      )) }),
      /* @__PURE__ */ jsxs13("div", { className: "langley-header-right", children: [
        /* @__PURE__ */ jsx14(
          "button",
          {
            className: "langley-btn langley-theme-toggle",
            onClick: toggleTheme,
            "data-testid": "theme-toggle",
            title: `Switch to ${theme === "dark" ? "light" : "dark"} theme`,
            children: theme === "dark" ? "\u2600" : "\u263E"
          }
        ),
        /* @__PURE__ */ jsx14(
          "span",
          {
            className: `langley-connection-status${state.connected ? " connected" : ""}`,
            "data-testid": "connection-status",
            children: state.connected ? "Connected" : "Disconnected"
          }
        )
      ] })
    ] }),
    /* @__PURE__ */ jsxs13("main", { className: "langley-main", children: [
      state.error && /* @__PURE__ */ jsx14("div", { className: "langley-error", "data-testid": "error-banner", children: state.error }),
      /* @__PURE__ */ jsxs13("regular-layout", { ref: layoutRef, "data-testid": "layout-container", children: [
        /* @__PURE__ */ jsx14("regular-layout-frame", { name: "status", "data-testid": "panel-status", children: /* @__PURE__ */ jsx14(
          StatusTab,
          {
            agents: state.agents,
            activity,
            onAgentsChanged,
            onNavigateChat: handleNavigateChat,
            onNavigateInspect: handleNavigateInspect,
            onBulkAction: handleBulkAction
          }
        ) }),
        /* @__PURE__ */ jsx14("regular-layout-frame", { name: "chat", "data-testid": "panel-chat", children: /* @__PURE__ */ jsx14(
          ChatTab,
          {
            agents: state.agents,
            initialAgentId: chatInitialAgent,
            wsClient: wsRef.current
          }
        ) }),
        /* @__PURE__ */ jsx14("regular-layout-frame", { name: "logs", "data-testid": "panel-logs", children: /* @__PURE__ */ jsx14(LogsTab, { agents: state.agents }) }),
        /* @__PURE__ */ jsx14("regular-layout-frame", { name: "messages", "data-testid": "panel-messages", children: /* @__PURE__ */ jsx14(MessageInspectorTab, {}) }),
        /* @__PURE__ */ jsx14("regular-layout-frame", { name: "traces", "data-testid": "panel-traces", children: /* @__PURE__ */ jsx14(TraceTab, { agents: state.agents }) }),
        /* @__PURE__ */ jsx14("regular-layout-frame", { name: "profiles", "data-testid": "panel-profiles", children: /* @__PURE__ */ jsx14(ProfilesTab, {}) })
      ] }),
      inspector && /* @__PURE__ */ jsxs13(
        "div",
        {
          className: "langley-overlay-inspector",
          "data-testid": "panel-agent-inspector",
          children: [
            /* @__PURE__ */ jsxs13("div", { className: "langley-overlay-header", children: [
              /* @__PURE__ */ jsx14("span", { className: "langley-overlay-title", children: "Agent Inspector" }),
              /* @__PURE__ */ jsx14(
                "button",
                {
                  className: "langley-btn langley-overlay-close",
                  onClick: () => setInspector(void 0),
                  "data-testid": "close-inspector",
                  children: "\xD7"
                }
              )
            ] }),
            /* @__PURE__ */ jsx14("div", { className: "langley-overlay-body", children: /* @__PURE__ */ jsx14(
              AgentInspector,
              {
                agentId: inspector.agentId,
                onBack: () => setInspector(void 0),
                onAction: () => onAgentsChanged()
              }
            ) })
          ]
        }
      )
    ] })
  ] });
}

// src/ts/index.tsx
import { jsx as jsx15 } from "react/jsx-runtime";
var root = document.getElementById("root");
if (root) {
  createRoot(root).render(
    /* @__PURE__ */ jsx15(StrictMode, { children: /* @__PURE__ */ jsx15(App, {}) })
  );
}
