// src/tui/opentuiMain.tsx
import { createCliRenderer } from "@opentui/core";
import { createRoot } from "@opentui/react";

// src/tui/opentui/DocyrusOpenTuiApp.tsx
import { RGBA as RGBA2 } from "@opentui/core";
import { useKeyboard as useKeyboard2, useRenderer } from "@opentui/react";
import { useCallback as useCallback2, useEffect, useMemo, useRef, useState as useState2 } from "react";

// src/services/tuiProcessExecutor.ts
import { spawnSync } from "node:child_process";

// src/errors.ts
var ApplicationError = class extends Error {
  constructor(message, data = {}, httpStatusCode = 500) {
    super(message);
    this.data = data;
    this.httpStatusCode = httpStatusCode;
  }
  data;
  httpStatusCode;
};
var UserInputError = class extends ApplicationError {
  constructor(message, data = {}) {
    super(message, data, 400);
  }
};

// src/services/tuiProcessExecutor.ts
function normalizeCommandArg(arg) {
  return arg.trim();
}
function sanitizeTuiCommandArgs(args) {
  const normalized = args.map(normalizeCommandArg).filter((value) => value.length > 0);
  const withoutBinary = normalized[0] === "docyrus" ? normalized.slice(1) : normalized;
  const withoutJson = withoutBinary.filter((value) => value !== "--json");
  const firstArg = withoutJson[0];
  if (firstArg === "tui" || firstArg === "interactive") {
    throw new UserInputError("Already in TUI session.");
  }
  return withoutJson;
}
function parseJsonOutput(rawOutput) {
  const trimmedOutput = rawOutput.trim();
  if (!trimmedOutput) {
    throw new UserInputError("Command produced no output.");
  }
  const lines = trimmedOutput.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
  const lastLine = lines.at(-1);
  if (lastLine) {
    try {
      return {
        data: JSON.parse(lastLine),
        messages: lines.slice(0, -1)
      };
    } catch {
    }
  }
  try {
    return {
      data: JSON.parse(trimmedOutput),
      messages: []
    };
  } catch (error) {
    throw new UserInputError("Invalid command output format. Expected JSON output.", {
      cause: error,
      rawOutput: trimmedOutput
    });
  }
}
function toErrorMessage(error) {
  if (error instanceof Error && error.message.trim().length > 0) {
    return error.message;
  }
  return "Failed to execute command.";
}
function createTuiProcessExecutor(options) {
  const spawnCommand = options.spawnSyncFn ?? spawnSync;
  const now = options.now ?? Date.now;
  const runCliCommand = async (args) => {
    const startedAt = now();
    let commandArgs = [];
    let commandLabel = "";
    let rawOutput = "";
    let messageLines = [];
    try {
      commandArgs = sanitizeTuiCommandArgs(args);
      commandLabel = commandArgs.join(" ").trim();
      const spawnResult = spawnCommand(
        options.executionConfig.executable,
        [
          options.executionConfig.scriptPath,
          ...commandArgs,
          "--json"
        ],
        {
          encoding: "utf8",
          cwd: options.executionConfig.cwd,
          env: {
            ...process.env,
            ...options.executionConfig.env || {}
          }
        }
      );
      const stdout = spawnResult.stdout?.toString() || "";
      const stderr = spawnResult.stderr?.toString() || "";
      rawOutput = stdout.trim();
      if (spawnResult.error) {
        throw spawnResult.error;
      }
      if (spawnResult.status !== 0) {
        const details = [rawOutput, stderr.trim()].filter((line) => line.length > 0).join("\n");
        return {
          ok: false,
          command: commandLabel,
          rawOutput: details,
          error: {
            message: stderr.trim() || `Command exited with code ${spawnResult.status ?? "unknown"}.`,
            details: details || void 0
          },
          durationMs: now() - startedAt
        };
      }
      const parsed = parseJsonOutput(stdout);
      messageLines = parsed.messages;
      return {
        ok: true,
        command: commandLabel,
        rawOutput,
        data: parsed.data,
        durationMs: now() - startedAt,
        messages: messageLines.length > 0 ? messageLines : void 0
      };
    } catch (error) {
      return {
        ok: false,
        command: commandLabel,
        rawOutput,
        error: {
          message: toErrorMessage(error),
          details: rawOutput || void 0
        },
        durationMs: now() - startedAt,
        messages: messageLines.length > 0 ? messageLines : void 0
      };
    }
  };
  return {
    runCliCommand
  };
}

// src/tui/opentui/commandInput.ts
import { useKeyboard } from "@opentui/react";
import { useCallback, useState } from "react";
function parseCommandLine(command) {
  const args = [];
  let current = "";
  let quote = null;
  let escaped = false;
  for (const char of command) {
    if (escaped) {
      current += char;
      escaped = false;
      continue;
    }
    if (char === "\\") {
      escaped = true;
      continue;
    }
    if (quote) {
      if (char === quote) {
        quote = null;
      } else {
        current += char;
      }
      continue;
    }
    if (char === '"' || char === "'") {
      quote = char;
      continue;
    }
    if (/\s/.test(char)) {
      if (current.length > 0) {
        args.push(current);
        current = "";
      }
      continue;
    }
    current += char;
  }
  if (quote) {
    throw new Error("Invalid command syntax: unmatched quote.");
  }
  if (escaped) {
    current += "\\";
  }
  if (current.length > 0) {
    args.push(current);
  }
  return args;
}
function preventDefault(event) {
  if (typeof event.preventDefault === "function") {
    event.preventDefault();
  }
}
function useCommandInput(options) {
  const [history, setHistory] = useState([]);
  const [historyCursor, setHistoryCursor] = useState(null);
  const [draftInput, setDraftInput] = useState("");
  const submitInput = useCallback((value) => {
    if (options.busy) {
      return;
    }
    const trimmed = (value ?? options.input).trim();
    if (trimmed.length === 0) {
      return;
    }
    setHistory((previous) => {
      if (previous[0] === trimmed) {
        return previous;
      }
      return [trimmed, ...previous];
    });
    setHistoryCursor(null);
    setDraftInput("");
    options.setInput("");
    options.onSubmit(trimmed);
  }, [options]);
  const recallHistory = useCallback((direction) => {
    if (history.length === 0) {
      return;
    }
    if (direction === "up") {
      if (historyCursor === null) {
        setDraftInput(options.input);
        setHistoryCursor(0);
        options.setInput(history[0] || "");
        return;
      }
      const nextCursor2 = Math.min(historyCursor + 1, history.length - 1);
      setHistoryCursor(nextCursor2);
      options.setInput(history[nextCursor2] || "");
      return;
    }
    if (historyCursor === null) {
      return;
    }
    const nextCursor = historyCursor - 1;
    if (nextCursor < 0) {
      setHistoryCursor(null);
      options.setInput(draftInput);
      return;
    }
    setHistoryCursor(nextCursor);
    options.setInput(history[nextCursor] || "");
  }, [draftInput, history, historyCursor, options]);
  useKeyboard((keyEvent) => {
    if (options.isModalOpen) {
      return;
    }
    const keyName = keyEvent.name;
    const hotkeysEnabled = options.hotkeysEnabled !== false;
    const sectionTabEnabled = hotkeysEnabled && options.sectionTabEnabled !== false;
    const inputUpHistoryEnabled = options.inputUpHistoryEnabled !== false;
    if (keyEvent.ctrl && keyName === "l") {
      preventDefault(keyEvent);
      options.onClear();
      return;
    }
    if (sectionTabEnabled && keyName === "tab") {
      preventDefault(keyEvent);
      if (keyEvent.shift) {
        options.onPreviousSection();
        return;
      }
      options.onNextSection();
      return;
    }
    if (hotkeysEnabled && keyName === "[") {
      preventDefault(keyEvent);
      options.onPreviousSection();
      return;
    }
    if (hotkeysEnabled && keyName === "]") {
      preventDefault(keyEvent);
      options.onNextSection();
      return;
    }
    if (inputUpHistoryEnabled && options.isInputFocused && keyName === "up") {
      preventDefault(keyEvent);
      recallHistory("up");
      return;
    }
    if (options.isInputFocused && keyName === "down") {
      preventDefault(keyEvent);
      recallHistory("down");
      return;
    }
    if (options.busy) {
      return;
    }
    if (hotkeysEnabled && options.input.length === 0 && /^[1-6]$/.test(keyName)) {
      preventDefault(keyEvent);
      options.onShortcut(Number(keyName));
    }
  });
  return {
    submitInput
  };
}

// src/tui/opentui/dataSourceCatalog.ts
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function toNonEmptyString(value) {
  if (typeof value !== "string") {
    return void 0;
  }
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : void 0;
}
function toStringValue(value, fallback) {
  return toNonEmptyString(value) || fallback;
}
function getArrayCandidates(payload) {
  if (Array.isArray(payload)) {
    return payload;
  }
  if (!isRecord(payload)) {
    return [];
  }
  const directData = payload.data;
  if (Array.isArray(directData)) {
    return directData;
  }
  if (isRecord(directData) && Array.isArray(directData.data)) {
    return directData.data;
  }
  if (Array.isArray(payload.items)) {
    return payload.items;
  }
  if (Array.isArray(payload.dataSources)) {
    return payload.dataSources;
  }
  return [];
}
function compareByName(a, b) {
  return a.localeCompare(b, void 0, { sensitivity: "base" });
}
function getDataSourceDisplayName(dataSource) {
  return dataSource.title || dataSource.name || dataSource.slug;
}
function extractAppsFromPayload(payload) {
  const result = [];
  const seen = /* @__PURE__ */ new Set();
  for (const candidate of getArrayCandidates(payload)) {
    if (!isRecord(candidate)) {
      continue;
    }
    const id = toNonEmptyString(candidate.id);
    const slug = toNonEmptyString(candidate.slug);
    if (!id || !slug) {
      continue;
    }
    const name = toStringValue(candidate.name, slug);
    const dedupeKey = `${id}::${slug}`;
    if (seen.has(dedupeKey)) {
      continue;
    }
    seen.add(dedupeKey);
    result.push({ id, slug, name });
  }
  result.sort((a, b) => compareByName(a.name, b.name));
  return result;
}
function extractDataSourcesFromPayload(payload) {
  const result = [];
  const seen = /* @__PURE__ */ new Set();
  for (const candidate of getArrayCandidates(payload)) {
    if (!isRecord(candidate)) {
      continue;
    }
    const id = toNonEmptyString(candidate.id);
    const slug = toNonEmptyString(candidate.slug);
    if (!id || !slug) {
      continue;
    }
    const title = toNonEmptyString(candidate.title);
    const name = toStringValue(candidate.name, slug);
    const appSlug = toNonEmptyString(candidate.app_slug);
    const tenantAppId = toNonEmptyString(candidate.tenant_app_id);
    const dedupeKey = `${id}::${slug}`;
    if (seen.has(dedupeKey)) {
      continue;
    }
    seen.add(dedupeKey);
    result.push({
      id,
      name,
      title,
      slug,
      app_slug: appSlug,
      tenant_app_id: tenantAppId
    });
  }
  result.sort((a, b) => compareByName(getDataSourceDisplayName(a), getDataSourceDisplayName(b)));
  return result;
}
function groupDataSourcesByApp(params) {
  const { apps, dataSources } = params;
  const appById = /* @__PURE__ */ new Map();
  const appBySlug = /* @__PURE__ */ new Map();
  const groups = /* @__PURE__ */ new Map();
  for (const app of apps) {
    appById.set(app.id, app);
    appBySlug.set(app.slug, app);
  }
  for (const dataSource of dataSources) {
    const byId = dataSource.tenant_app_id ? appById.get(dataSource.tenant_app_id) : void 0;
    const bySlug = dataSource.app_slug ? appBySlug.get(dataSource.app_slug) : void 0;
    const matchedApp = byId || bySlug;
    const appKey = matchedApp ? matchedApp.id : dataSource.app_slug ? `slug:${dataSource.app_slug}` : "unknown";
    const group = groups.get(appKey) || {
      appKey,
      appId: matchedApp?.id || dataSource.tenant_app_id,
      appName: matchedApp?.name || dataSource.app_slug || "Unknown App",
      appSlug: matchedApp?.slug || dataSource.app_slug,
      dataSources: []
    };
    group.dataSources.push(dataSource);
    groups.set(appKey, group);
  }
  const list = Array.from(groups.values());
  for (const group of list) {
    group.dataSources.sort((a, b) => compareByName(getDataSourceDisplayName(a), getDataSourceDisplayName(b)));
  }
  list.sort((a, b) => compareByName(a.appName, b.appName));
  return list;
}
function filterDataSources(groups, query) {
  const normalizedQuery = query.trim().toLowerCase();
  if (normalizedQuery.length === 0) {
    return groups;
  }
  return groups.map((group) => {
    const filteredDataSources = group.dataSources.filter((dataSource) => {
      const haystack = [
        dataSource.title,
        dataSource.name,
        dataSource.slug
      ].filter((value) => Boolean(value)).join(" ").toLowerCase();
      return haystack.includes(normalizedQuery);
    });
    return {
      ...group,
      dataSources: filteredDataSources
    };
  }).filter((group) => group.dataSources.length > 0);
}
function flattenTreeRows(params) {
  const rows = [];
  const alwaysExpanded = params.query.trim().length > 0;
  for (const group of params.groups) {
    const expanded = alwaysExpanded || params.expandedAppKeys.has(group.appKey);
    rows.push({
      id: `app:${group.appKey}`,
      kind: "app",
      appKey: group.appKey,
      appName: group.appName,
      appSlug: group.appSlug,
      expanded
    });
    if (!expanded) {
      continue;
    }
    for (const dataSource of group.dataSources) {
      const dataSourceName = getDataSourceDisplayName(dataSource);
      rows.push({
        id: `ds:${group.appKey}:${dataSource.id}`,
        kind: "datasource",
        appKey: group.appKey,
        appName: group.appName,
        appSlug: group.appSlug || dataSource.app_slug,
        dataSourceId: dataSource.id,
        dataSourceName,
        dataSourceSlug: dataSource.slug
      });
    }
  }
  return rows;
}

// src/tui/opentui/renderResult.tsx
import { RGBA, SyntaxStyle } from "@opentui/core";

// src/tui/opentui/resultDocument.ts
function toErrorPayload(entry) {
  return {
    message: entry.result.error?.message || "Command failed.",
    details: entry.result.error?.details
  };
}
function buildPayload(entry) {
  if (entry.result.ok) {
    return entry.result.data ?? null;
  }
  return toErrorPayload(entry);
}
function buildResultDocument(entry) {
  return {
    command: entry.command || "(root)",
    ok: entry.result.ok,
    durationMs: entry.result.durationMs,
    timestamp: new Date(entry.createdAt).toISOString(),
    payload: buildPayload(entry),
    messages: entry.result.messages,
    rawOutput: entry.result.rawOutput || void 0
  };
}
function serializeResultDocument(document) {
  try {
    const result = JSON.stringify(document, null, 2);
    if (!result) {
      return "null";
    }
    return result;
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    return JSON.stringify({
      command: document.command,
      ok: false,
      durationMs: document.durationMs,
      timestamp: document.timestamp,
      payload: {
        message: "Serialization failed",
        details: message
      }
    }, null, 2);
  }
}

// src/tui/opentui/renderResult.tsx
import { jsx, jsxs } from "@opentui/react/jsx-runtime";
var RESULT_VIEW_OPTIONS = [
  { name: "PRETTY", description: "Markdown view", value: "pretty" },
  { name: "JSON", description: "Raw JSON view", value: "json" }
];
var jsonSyntaxStyle = null;
function getJsonSyntaxStyle() {
  if (jsonSyntaxStyle) {
    return jsonSyntaxStyle;
  }
  jsonSyntaxStyle = SyntaxStyle.fromStyles({
    default: {
      fg: RGBA.fromHex("#d4d4d4")
    },
    property: {
      fg: RGBA.fromHex("#9cdcfe")
    },
    string: {
      fg: RGBA.fromHex("#ce9178")
    },
    number: {
      fg: RGBA.fromHex("#b5cea8")
    },
    keyword: {
      fg: RGBA.fromHex("#569cd6")
    },
    constant: {
      fg: RGBA.fromHex("#4fc1ff")
    },
    punctuation: {
      fg: RGBA.fromHex("#c586c0")
    },
    operator: {
      fg: RGBA.fromHex("#d4d4d4")
    }
  });
  return jsonSyntaxStyle;
}
function isRecord2(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function escapeMd(value) {
  return value.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\n/g, "<br/>");
}
function inlineValue(value) {
  if (value === null) {
    return "`null`";
  }
  if (value === void 0) {
    return "`undefined`";
  }
  if (typeof value === "string") {
    return escapeMd(value);
  }
  if (typeof value === "number" || typeof value === "boolean") {
    return `\`${String(value)}\``;
  }
  if (Array.isArray(value)) {
    return `\`[${value.length} items]\``;
  }
  if (isRecord2(value)) {
    return `\`{${Object.keys(value).length} keys}\``;
  }
  return escapeMd(String(value));
}
function headingForDepth(depth) {
  const safeDepth = Math.min(6, Math.max(2, depth + 2));
  return "#".repeat(safeDepth);
}
function renderObjectMarkdown(record, depth, sectionTitle) {
  const entries = Object.entries(record);
  if (entries.length === 0) {
    return `${headingForDepth(depth)} ${sectionTitle}

_Empty object_
`;
  }
  const lines = [];
  lines.push(`${headingForDepth(depth)} ${sectionTitle}`);
  lines.push("");
  lines.push("| Key | Value |");
  lines.push("| --- | --- |");
  const nestedSections = [];
  for (const [key, value] of entries) {
    const escapedKey = escapeMd(key);
    if (Array.isArray(value) || isRecord2(value)) {
      lines.push(`| ${escapedKey} | ${inlineValue(value)} |`);
      nestedSections.push(renderAnyMarkdown(value, depth + 1, key));
      continue;
    }
    lines.push(`| ${escapedKey} | ${inlineValue(value)} |`);
  }
  if (nestedSections.length > 0) {
    lines.push("");
    lines.push(...nestedSections);
  }
  return `${lines.join("\n")}
`;
}
function renderArrayMarkdown(values, depth, sectionTitle) {
  const lines = [];
  lines.push(`${headingForDepth(depth)} ${sectionTitle}`);
  lines.push("");
  if (values.length === 0) {
    lines.push("_Empty array_");
    return `${lines.join("\n")}
`;
  }
  const firstItem = values[0];
  if (isRecord2(firstItem)) {
    const headers = Object.keys(firstItem);
    lines.push(`| ${headers.map(escapeMd).join(" | ")} |`);
    lines.push(`| ${headers.map(() => "---").join(" | ")} |`);
    const nestedSections2 = [];
    values.forEach((item, index) => {
      if (!isRecord2(item)) {
        lines.push(`| ${escapeMd(String(item))} |`);
        return;
      }
      const rowCells = headers.map((header) => {
        const cellValue = item[header];
        if (Array.isArray(cellValue) || isRecord2(cellValue)) {
          nestedSections2.push(renderAnyMarkdown(cellValue, depth + 1, `${sectionTitle}[${index}].${header}`));
        }
        return inlineValue(cellValue);
      });
      lines.push(`| ${rowCells.join(" | ")} |`);
    });
    if (nestedSections2.length > 0) {
      lines.push("");
      lines.push(...nestedSections2);
    }
    return `${lines.join("\n")}
`;
  }
  lines.push("| Index | Value |");
  lines.push("| --- | --- |");
  const nestedSections = [];
  values.forEach((value, index) => {
    if (Array.isArray(value) || isRecord2(value)) {
      lines.push(`| ${index} | ${inlineValue(value)} |`);
      nestedSections.push(renderAnyMarkdown(value, depth + 1, `${sectionTitle}[${index}]`));
      return;
    }
    lines.push(`| ${index} | ${inlineValue(value)} |`);
  });
  if (nestedSections.length > 0) {
    lines.push("");
    lines.push(...nestedSections);
  }
  return `${lines.join("\n")}
`;
}
function renderAnyMarkdown(value, depth, sectionTitle) {
  if (Array.isArray(value)) {
    return renderArrayMarkdown(value, depth, sectionTitle);
  }
  if (isRecord2(value)) {
    return renderObjectMarkdown(value, depth, sectionTitle);
  }
  return `${headingForDepth(depth)} ${sectionTitle}

${inlineValue(value)}
`;
}
function resolvePrettyPayload(document) {
  const payload = document.payload;
  if (!isRecord2(payload)) {
    return payload;
  }
  const status = typeof payload.status === "number" ? payload.status : void 0;
  const success = typeof payload.success === "boolean" ? payload.success : void 0;
  if (typeof status === "number") {
    if (status >= 400) {
      if ("error" in payload) {
        return payload.error;
      }
      if (isRecord2(payload.data) && "error" in payload.data) {
        return payload.data.error;
      }
      return payload;
    }
    if ("data" in payload) {
      return payload.data;
    }
    return payload;
  }
  if (success === true) {
    if ("data" in payload) {
      return payload.data;
    }
    return payload;
  }
  if (success === false) {
    if ("error" in payload) {
      return payload.error;
    }
    return payload;
  }
  if (document.ok && "data" in payload) {
    return payload.data;
  }
  if (!document.ok && "error" in payload) {
    return payload.error;
  }
  return payload;
}
function buildPrettyMarkdown(document) {
  const payload = resolvePrettyPayload(document);
  return renderAnyMarkdown(payload, 0, document.ok ? "Data" : "Error");
}
function renderResult(params) {
  const {
    entry,
    isFocused,
    viewMode,
    onViewModeChange,
    resultScrollRef
  } = params;
  if (!entry) {
    return /* @__PURE__ */ jsx("text", { fg: "yellow", children: "No command executed yet." });
  }
  const document = buildResultDocument(entry);
  const json = serializeResultDocument(document);
  const markdown = buildPrettyMarkdown(document);
  const viewOptions = viewMode === "pretty" ? RESULT_VIEW_OPTIONS : [RESULT_VIEW_OPTIONS[1], RESULT_VIEW_OPTIONS[0]];
  return /* @__PURE__ */ jsxs("box", { flexDirection: "column", width: "100%", height: "100%", children: [
    /* @__PURE__ */ jsxs("box", { paddingBottom: 1, flexDirection: "column", children: [
      /* @__PURE__ */ jsxs("text", { fg: document.ok ? "green" : "red", children: [
        document.ok ? "OK" : "ERR",
        " ",
        document.command,
        " [",
        document.durationMs,
        "ms]"
      ] }),
      /* @__PURE__ */ jsx(
        "tab-select",
        {
          options: viewOptions,
          onChange: (_index, option) => {
            if (option?.value === "json") {
              onViewModeChange("json");
              return;
            }
            onViewModeChange("pretty");
          },
          onSelect: (_index, option) => {
            if (option?.value === "json") {
              onViewModeChange("json");
              return;
            }
            onViewModeChange("pretty");
          },
          focused: false
        }
      )
    ] }),
    /* @__PURE__ */ jsx("box", { flexGrow: 1, width: "100%", height: "100%", children: /* @__PURE__ */ jsx("scrollbox", { ref: resultScrollRef, focused: isFocused, scrollX: true, scrollY: true, style: { height: "100%" }, children: viewMode === "json" ? /* @__PURE__ */ jsx(
      "code",
      {
        width: "100%",
        content: json,
        filetype: "json",
        syntaxStyle: getJsonSyntaxStyle(),
        streaming: false,
        conceal: false
      }
    ) : /* @__PURE__ */ jsx(
      "markdown",
      {
        content: markdown,
        syntaxStyle: getJsonSyntaxStyle(),
        streaming: false,
        tableOptions: {
          widthMode: "content",
          wrapMode: "none",
          borders: true
        }
      }
    ) }) })
  ] });
}

// src/tui/opentui/DocyrusOpenTuiApp.tsx
import { jsx as jsx2, jsxs as jsxs2 } from "@opentui/react/jsx-runtime";
var SHORTCUTS = [
  {
    id: 1,
    run: "env list",
    label: "env list"
  },
  {
    id: 2,
    run: "auth who",
    label: "auth who"
  },
  {
    id: 3,
    run: "apps list",
    label: "apps list"
  },
  {
    id: 4,
    run: "discover namespaces",
    label: "discover namespaces"
  },
  {
    id: 5,
    template: "studio list-data-sources --appSlug ",
    label: "insert: studio list-data-sources --appSlug "
  },
  {
    id: 6,
    template: "ds list <appSlug> <dataSourceSlug>",
    label: "insert: ds list <appSlug> <dataSourceSlug>"
  }
];
var SECTION_ORDER = ["shortcuts", "datasources", "history", "messages", "help"];
var FOCUS_ORDER = ["input", "left", "result"];
var ESC_ARM_TIMEOUT_MS = 1400;
function isRecord3(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function extractMetadata(payload) {
  if (!isRecord3(payload)) {
    return {};
  }
  const environmentValue = payload.environment;
  const contextValue = payload.context;
  const environment = isRecord3(environmentValue) && typeof environmentValue.id === "string" && typeof environmentValue.name === "string" ? { id: environmentValue.id, name: environmentValue.name } : void 0;
  if (contextValue === null) {
    return {
      environment,
      context: null
    };
  }
  const context = isRecord3(contextValue) && typeof contextValue.email === "string" && typeof contextValue.tenantDisplay === "string" ? {
    email: contextValue.email,
    tenantDisplay: contextValue.tenantDisplay
  } : void 0;
  return {
    environment,
    context
  };
}
function toFailedResult(error, command) {
  const message = error instanceof Error ? error.message : "Invalid command syntax.";
  return {
    ok: false,
    command,
    rawOutput: "",
    error: {
      message
    },
    durationMs: 0
  };
}
function formatHistoryLabel(entry) {
  const status = entry.result.ok ? "OK" : "ERR";
  const command = entry.command || "(root)";
  return `${status} ${command} [${entry.result.durationMs}ms]`;
}
function preventDefault2(keyEvent) {
  if (typeof keyEvent.preventDefault === "function") {
    keyEvent.preventDefault();
  }
}
function isEscapeKey(keyName) {
  return keyName === "escape" || keyName === "esc";
}
function isEnterKey(keyName) {
  return keyName === "enter" || keyName === "return";
}
function isSlashKey(keyName) {
  return keyName === "/" || keyName === "slash";
}
function toCatalogErrorMessage(command, result) {
  const details = result.error?.details || result.error?.message || "Unknown error.";
  if (details.includes("Architect.Read.All") || details.includes("Architect.ReadWrite.All")) {
    return `${command} failed: missing required scope Architect.Read.All or Architect.ReadWrite.All.`;
  }
  const message = result.error?.message || "Command failed.";
  return `${command} failed: ${message}`;
}
function isScrollAtBottom(scrollBox) {
  if (!scrollBox) {
    return true;
  }
  const viewportHeight = scrollBox.viewport.height;
  const maxScrollTop = Math.max(0, scrollBox.scrollHeight - viewportHeight);
  if (maxScrollTop <= 0) {
    return true;
  }
  return scrollBox.scrollTop >= maxScrollTop - 1;
}
function DocyrusOpenTuiApp(props) {
  const renderer = useRenderer();
  const [input, setInput] = useState2("");
  const [entries, setEntries] = useState2([]);
  const [activeEntryId, setActiveEntryId] = useState2(null);
  const [systemMessages, setSystemMessages] = useState2([]);
  const [activeSection, setActiveSection] = useState2("shortcuts");
  const [focusedPanel, setFocusedPanel] = useState2("left");
  const [environment, setEnvironment] = useState2();
  const [context, setContext] = useState2(void 0);
  const [isRunning, setIsRunning] = useState2(false);
  const [spinnerFrame, setSpinnerFrame] = useState2(0);
  const [selectedShortcutIndex, setSelectedShortcutIndex] = useState2(0);
  const [selectedHistoryIndex, setSelectedHistoryIndex] = useState2(0);
  const [isExitConfirmOpen, setIsExitConfirmOpen] = useState2(false);
  const [isEscArmed, setIsEscArmed] = useState2(false);
  const [resultViewMode, setResultViewMode] = useState2("pretty");
  const [dataSourceSearch, setDataSourceSearch] = useState2("");
  const [dataSourcePanelFocus, setDataSourcePanelFocus] = useState2("tree");
  const [selectedDataSourceRowIndex, setSelectedDataSourceRowIndex] = useState2(0);
  const [expandedAppKeys, setExpandedAppKeys] = useState2([]);
  const [appsCatalog, setAppsCatalog] = useState2([]);
  const [dataSourcesCatalog, setDataSourcesCatalog] = useState2([]);
  const [isCatalogLoading, setIsCatalogLoading] = useState2(false);
  const [catalogError, setCatalogError] = useState2(null);
  const [catalogLoadedAt, setCatalogLoadedAt] = useState2(null);
  const catalogScopeRef = useRef("");
  const resultScrollRef = useRef(null);
  const leftScrollRef = useRef(null);
  const commandInputRef = useRef(null);
  const executor = useMemo(() => {
    return createTuiProcessExecutor({
      executionConfig: props.executionConfig
    });
  }, [props.executionConfig]);
  const applyMetadataFromPayload = useCallback2((payload) => {
    const metadata = extractMetadata(payload);
    if (metadata.environment) {
      setEnvironment(metadata.environment);
    }
    if (metadata.context !== void 0) {
      setContext(metadata.context);
    }
  }, []);
  const appendSystemMessages = useCallback2((messages) => {
    if (messages.length === 0) {
      return;
    }
    setSystemMessages((previous) => [...previous, ...messages]);
  }, []);
  const applyCommandResult = useCallback2((result, command) => {
    const entry = {
      id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
      command,
      result,
      createdAt: Date.now()
    };
    setEntries((previous) => [entry, ...previous]);
    setActiveEntryId(entry.id);
    setSelectedHistoryIndex(0);
    if (result.messages && result.messages.length > 0) {
      appendSystemMessages(result.messages);
    }
    if (result.ok && result.data !== void 0) {
      applyMetadataFromPayload(result.data);
    }
  }, [appendSystemMessages, applyMetadataFromPayload]);
  const executeArgs = useCallback2(async (args, commandText) => {
    setIsRunning(true);
    try {
      const result = await executor.runCliCommand(args);
      applyCommandResult(result, commandText);
    } finally {
      setIsRunning(false);
    }
  }, [applyCommandResult, executor]);
  const runInternalArgs = useCallback2(async (args) => {
    const result = await executor.runCliCommand(args);
    if (result.ok && result.data !== void 0) {
      applyMetadataFromPayload(result.data);
    }
    return result;
  }, [applyMetadataFromPayload, executor]);
  const executeLine = useCallback2((line) => {
    let args;
    try {
      args = parseCommandLine(line);
    } catch (error) {
      applyCommandResult(toFailedResult(error, line.trim()), line.trim());
      return;
    }
    if (args.length === 0) {
      return;
    }
    void executeArgs(args, line.trim());
  }, [applyCommandResult, executeArgs]);
  const runHistoryEntry = useCallback2(async (entry) => {
    if (entry.command === "(root)") {
      await executeArgs([], "(root)");
      return;
    }
    try {
      const args = parseCommandLine(entry.command);
      await executeArgs(args, entry.command);
    } catch (error) {
      applyCommandResult(toFailedResult(error, entry.command), entry.command);
    }
  }, [applyCommandResult, executeArgs]);
  const applyShortcut = useCallback2((shortcutId) => {
    const action = SHORTCUTS.find((shortcut) => shortcut.id === shortcutId);
    if (!action || isRunning || isCatalogLoading) {
      return;
    }
    if (action.template) {
      setInput(action.template);
      setFocusedPanel("input");
      return;
    }
    if (action.run) {
      void executeArgs(parseCommandLine(action.run), action.run);
    }
  }, [executeArgs, isCatalogLoading, isRunning]);
  const groupedDataSourceItems = useMemo(() => {
    return groupDataSourcesByApp({
      apps: appsCatalog,
      dataSources: dataSourcesCatalog
    });
  }, [appsCatalog, dataSourcesCatalog]);
  const filteredDataSourceGroups = useMemo(() => {
    return filterDataSources(groupedDataSourceItems, dataSourceSearch);
  }, [dataSourceSearch, groupedDataSourceItems]);
  const dataSourceCountByAppKey = useMemo(() => {
    const result = /* @__PURE__ */ new Map();
    for (const group of filteredDataSourceGroups) {
      result.set(group.appKey, group.dataSources.length);
    }
    return result;
  }, [filteredDataSourceGroups]);
  const expandedAppKeySet = useMemo(() => {
    return new Set(expandedAppKeys);
  }, [expandedAppKeys]);
  const dataSourceRows = useMemo(() => {
    return flattenTreeRows({
      groups: filteredDataSourceGroups,
      expandedAppKeys: expandedAppKeySet,
      query: dataSourceSearch
    });
  }, [dataSourceSearch, expandedAppKeySet, filteredDataSourceGroups]);
  const selectedDataSourceRow = useMemo(() => {
    if (dataSourceRows.length === 0) {
      return null;
    }
    return dataSourceRows[selectedDataSourceRowIndex] || dataSourceRows[0] || null;
  }, [dataSourceRows, selectedDataSourceRowIndex]);
  const toggleAppExpansion = useCallback2((appKey) => {
    setExpandedAppKeys((previous) => {
      if (previous.includes(appKey)) {
        return previous.filter((key) => key !== appKey);
      }
      return [...previous, appKey];
    });
  }, []);
  const loadDataSourceCatalog = useCallback2(async () => {
    if (isCatalogLoading) {
      return;
    }
    setIsCatalogLoading(true);
    setCatalogError(null);
    try {
      const nextMessages = [];
      const appsResult = await runInternalArgs(["apps", "list"]);
      const dataSourcesResult = await runInternalArgs(["curl", "/dev/data-sources"]);
      const nextApps = appsResult.ok && appsResult.data !== void 0 ? extractAppsFromPayload(appsResult.data) : [];
      const nextDataSources = dataSourcesResult.ok && dataSourcesResult.data !== void 0 ? extractDataSourcesFromPayload(dataSourcesResult.data) : [];
      if (!appsResult.ok) {
        nextMessages.push(toCatalogErrorMessage("apps list", appsResult));
      }
      if (!dataSourcesResult.ok) {
        nextMessages.push(toCatalogErrorMessage("curl /dev/data-sources", dataSourcesResult));
      }
      setAppsCatalog(nextApps);
      setDataSourcesCatalog(nextDataSources);
      setCatalogLoadedAt(Date.now());
      const nextGroups = groupDataSourcesByApp({
        apps: nextApps,
        dataSources: nextDataSources
      });
      setExpandedAppKeys((previous) => {
        if (previous.length > 0) {
          const allowed = new Set(nextGroups.map((group) => group.appKey));
          return previous.filter((key) => allowed.has(key));
        }
        return nextGroups.map((group) => group.appKey);
      });
      if (nextMessages.length > 0) {
        appendSystemMessages(nextMessages);
        setCatalogError(nextMessages[0] || "Failed to load catalog.");
      } else {
        setCatalogError(null);
      }
    } finally {
      setIsCatalogLoading(false);
    }
  }, [appendSystemMessages, isCatalogLoading, runInternalArgs]);
  const runSelectedDataSourceRow = useCallback2(async (row) => {
    if (!row || isRunning || isCatalogLoading) {
      return;
    }
    if (row.kind === "app") {
      toggleAppExpansion(row.appKey);
      return;
    }
    if (!row.appSlug || !row.dataSourceSlug) {
      appendSystemMessages([
        "Cannot execute ds get because selected row is missing appSlug or dataSourceSlug."
      ]);
      return;
    }
    const command = `ds get ${row.appSlug} ${row.dataSourceSlug}`;
    setFocusedPanel("result");
    await executeArgs(["ds", "get", row.appSlug, row.dataSourceSlug], command);
  }, [appendSystemMessages, executeArgs, isCatalogLoading, isRunning, toggleAppExpansion]);
  const setSectionByIndex = useCallback2((index) => {
    const safeIndex = index < 0 ? SECTION_ORDER.length - 1 : index >= SECTION_ORDER.length ? 0 : index;
    const section = SECTION_ORDER[safeIndex];
    if (section) {
      setActiveSection(section);
    }
  }, []);
  const nextSection = useCallback2(() => {
    const currentIndex = SECTION_ORDER.indexOf(activeSection);
    setSectionByIndex(currentIndex + 1);
  }, [activeSection, setSectionByIndex]);
  const previousSection = useCallback2(() => {
    const currentIndex = SECTION_ORDER.indexOf(activeSection);
    setSectionByIndex(currentIndex - 1);
  }, [activeSection, setSectionByIndex]);
  const setPanelByIndex = useCallback2((index) => {
    const safeIndex = index < 0 ? FOCUS_ORDER.length - 1 : index >= FOCUS_ORDER.length ? 0 : index;
    const panel = FOCUS_ORDER[safeIndex];
    if (panel) {
      setFocusedPanel(panel);
    }
  }, []);
  const nextPanel = useCallback2(() => {
    const currentIndex = FOCUS_ORDER.indexOf(focusedPanel);
    setPanelByIndex(currentIndex + 1);
  }, [focusedPanel, setPanelByIndex]);
  const previousPanel = useCallback2(() => {
    const currentIndex = FOCUS_ORDER.indexOf(focusedPanel);
    setPanelByIndex(currentIndex - 1);
  }, [focusedPanel, setPanelByIndex]);
  const openExitConfirmation = useCallback2(() => {
    setIsEscArmed(false);
    setIsExitConfirmOpen(true);
  }, []);
  const closeExitConfirmation = useCallback2(() => {
    setIsExitConfirmOpen(false);
    setIsEscArmed(false);
  }, []);
  const armEscapeExit = useCallback2(() => {
    setIsEscArmed(true);
    setSystemMessages((previous) => {
      const lastMessage = previous[previous.length - 1];
      const message = "Press Esc again to open exit confirmation.";
      if (lastMessage === message) {
        return previous;
      }
      return [...previous, message];
    });
  }, []);
  const isDataSourceSearchFocused = activeSection === "datasources" && focusedPanel === "left" && dataSourcePanelFocus === "search" && !isRunning && !isExitConfirmOpen;
  const { submitInput } = useCommandInput({
    busy: isRunning || isCatalogLoading,
    input,
    isInputFocused: focusedPanel === "input",
    isModalOpen: isExitConfirmOpen,
    hotkeysEnabled: !isRunning && !isDataSourceSearchFocused,
    sectionTabEnabled: focusedPanel !== "result",
    setInput,
    onSubmit: executeLine,
    onClear: () => {
      setEntries([]);
      setActiveEntryId(null);
      setSystemMessages([]);
      setSelectedHistoryIndex(0);
    },
    onShortcut: applyShortcut,
    onNextSection: nextSection,
    onPreviousSection: previousSection
  });
  useKeyboard2((keyEvent) => {
    const keyName = keyEvent.name;
    if (isExitConfirmOpen) {
      if (isEscapeKey(keyName)) {
        preventDefault2(keyEvent);
        closeExitConfirmation();
        return;
      }
      if (isEnterKey(keyName)) {
        preventDefault2(keyEvent);
        renderer.destroy();
        return;
      }
      if (keyEvent.ctrl && keyName === "c") {
        renderer.destroy();
      }
      return;
    }
    if (activeSection === "datasources" && focusedPanel === "left" && dataSourcePanelFocus === "search" && isEscapeKey(keyName)) {
      preventDefault2(keyEvent);
      setDataSourcePanelFocus("tree");
      return;
    }
    if (activeSection === "datasources" && focusedPanel === "left" && dataSourcePanelFocus === "tree" && isSlashKey(keyName)) {
      preventDefault2(keyEvent);
      setDataSourcePanelFocus("search");
      return;
    }
    if (keyEvent.ctrl && keyName === "c") {
      renderer.destroy();
      return;
    }
    if (focusedPanel === "result" && keyName === "tab" && !isRunning && !isCatalogLoading) {
      preventDefault2(keyEvent);
      setResultViewMode((previous) => previous === "pretty" ? "json" : "pretty");
      return;
    }
    if (isRunning) {
      return;
    }
    if (keyName === "down") {
      if (focusedPanel === "result") {
        if (isScrollAtBottom(resultScrollRef.current)) {
          preventDefault2(keyEvent);
          setIsEscArmed(false);
          setFocusedPanel("input");
        }
        return;
      }
      if (focusedPanel === "left") {
        let shouldSwitchToInput = false;
        if (activeSection === "shortcuts") {
          shouldSwitchToInput = shortcutOptions.length === 0 || selectedShortcutIndex >= shortcutOptions.length - 1;
        } else if (activeSection === "history") {
          shouldSwitchToInput = historyOptions.length === 0 || selectedHistoryIndex >= historyOptions.length - 1;
        } else if (activeSection === "datasources") {
          if (dataSourcePanelFocus === "tree") {
            shouldSwitchToInput = dataSourceOptions.length === 0 || selectedDataSourceRowIndex >= dataSourceOptions.length - 1;
          }
        } else if (activeSection === "messages" || activeSection === "help") {
          shouldSwitchToInput = isScrollAtBottom(leftScrollRef.current);
        }
        if (shouldSwitchToInput) {
          preventDefault2(keyEvent);
          setIsEscArmed(false);
          setFocusedPanel("input");
          return;
        }
      }
    }
    if (isEscapeKey(keyName)) {
      preventDefault2(keyEvent);
      if (focusedPanel !== "input") {
        setFocusedPanel("input");
        armEscapeExit();
        return;
      }
      if (!isEscArmed) {
        armEscapeExit();
        return;
      }
      openExitConfirmation();
      return;
    }
    if (activeSection === "datasources" && focusedPanel === "left" && dataSourcePanelFocus === "tree" && keyName === "space") {
      preventDefault2(keyEvent);
      if (selectedDataSourceRow?.kind === "app") {
        toggleAppExpansion(selectedDataSourceRow.appKey);
      }
      return;
    }
    if (keyName === "left" || keyName === "right") {
      if (focusedPanel === "input") {
        const cursorOffset = commandInputRef.current?.cursorOffset ?? input.length;
        const inputLength = input.length;
        const atStart = cursorOffset <= 0;
        const atEnd = cursorOffset >= inputLength;
        if (keyName === "left" && atStart) {
          preventDefault2(keyEvent);
          setIsEscArmed(false);
          setFocusedPanel("left");
          return;
        }
        if (keyName === "right" && atEnd) {
          preventDefault2(keyEvent);
          setIsEscArmed(false);
          setFocusedPanel("result");
          return;
        }
        return;
      }
      if (focusedPanel === "result") {
        const resultScroll = resultScrollRef.current;
        if (!resultScroll) {
          preventDefault2(keyEvent);
          setIsEscArmed(false);
          setFocusedPanel(keyName === "left" ? "left" : "input");
          return;
        }
        const viewportWidth = resultScroll.viewport.width;
        const maxScrollLeft = Math.max(0, resultScroll.scrollWidth - viewportWidth);
        const hasHorizontalScroll = maxScrollLeft > 0;
        const isAtStart = resultScroll.scrollLeft <= 0;
        const isAtEnd = resultScroll.scrollLeft >= maxScrollLeft - 1;
        if (!hasHorizontalScroll || keyName === "left" && isAtStart || keyName === "right" && isAtEnd) {
          preventDefault2(keyEvent);
          setIsEscArmed(false);
          setFocusedPanel(keyName === "left" ? "left" : "input");
          return;
        }
        return;
      }
      preventDefault2(keyEvent);
      setIsEscArmed(false);
      if (keyName === "left") {
        previousPanel();
      } else {
        nextPanel();
      }
      return;
    }
    if (keyName === "r" && activeSection === "datasources" && focusedPanel === "left" && dataSourcePanelFocus === "tree" && !isCatalogLoading) {
      preventDefault2(keyEvent);
      void loadDataSourceCatalog();
      return;
    }
    if (keyName === "r" && activeSection === "history" && focusedPanel === "left" && input.length === 0 && !isRunning && !isCatalogLoading) {
      const entry = entries[selectedHistoryIndex];
      if (entry) {
        void runHistoryEntry(entry);
      }
    }
  });
  useEffect(() => {
    void executeArgs([], "(root)");
  }, [executeArgs]);
  useEffect(() => {
    if (!isEscArmed) {
      return;
    }
    const timer = setTimeout(() => {
      setIsEscArmed(false);
    }, ESC_ARM_TIMEOUT_MS);
    return () => {
      clearTimeout(timer);
    };
  }, [isEscArmed]);
  useEffect(() => {
    if (!isRunning && !isCatalogLoading) {
      return;
    }
    const timer = setInterval(() => {
      setSpinnerFrame((previous) => (previous + 1) % 4);
    }, 120);
    return () => {
      clearInterval(timer);
    };
  }, [isCatalogLoading, isRunning]);
  useEffect(() => {
    if (selectedHistoryIndex < entries.length) {
      return;
    }
    const nextIndex = Math.max(entries.length - 1, 0);
    setSelectedHistoryIndex(nextIndex);
  }, [entries.length, selectedHistoryIndex]);
  useEffect(() => {
    if (selectedDataSourceRowIndex < dataSourceRows.length) {
      return;
    }
    const nextIndex = Math.max(dataSourceRows.length - 1, 0);
    setSelectedDataSourceRowIndex(nextIndex);
  }, [dataSourceRows.length, selectedDataSourceRowIndex]);
  useEffect(() => {
    if (activeSection !== "datasources" && dataSourcePanelFocus !== "tree") {
      setDataSourcePanelFocus("tree");
    }
  }, [activeSection, dataSourcePanelFocus]);
  useEffect(() => {
    const scopeKey = `${environment?.id || ""}::${context?.tenantDisplay || ""}`;
    if (catalogScopeRef.current.length === 0) {
      catalogScopeRef.current = scopeKey;
      return;
    }
    if (catalogScopeRef.current === scopeKey) {
      return;
    }
    catalogScopeRef.current = scopeKey;
    if (catalogLoadedAt !== null) {
      setCatalogLoadedAt(null);
      setAppsCatalog([]);
      setDataSourcesCatalog([]);
      setExpandedAppKeys([]);
      setSelectedDataSourceRowIndex(0);
      setCatalogError(null);
    }
  }, [catalogLoadedAt, context?.tenantDisplay, environment?.id]);
  useEffect(() => {
    if (activeSection !== "datasources" || catalogLoadedAt !== null || isCatalogLoading) {
      return;
    }
    void loadDataSourceCatalog();
  }, [activeSection, catalogLoadedAt, isCatalogLoading, loadDataSourceCatalog]);
  const spinner = useMemo(() => {
    return ["|", "/", "-", "\\"][spinnerFrame] || "|";
  }, [spinnerFrame]);
  const activeEntry = useMemo(() => {
    if (activeEntryId) {
      const found = entries.find((entry) => entry.id === activeEntryId);
      if (found) {
        return found;
      }
    }
    return entries[0] || null;
  }, [activeEntryId, entries]);
  const sectionOptions = useMemo(() => {
    const ordered = [
      activeSection,
      ...SECTION_ORDER.filter((section) => section !== activeSection)
    ];
    return ordered.map((section) => ({
      name: section === "shortcuts" ? "Shortcuts" : section === "datasources" ? "DataSources" : section === "history" ? "History" : section === "messages" ? "Messages" : "Help",
      description: section === "shortcuts" ? "Quick actions" : section === "datasources" ? "App tree" : section === "history" ? "Past runs" : section === "messages" ? "System output" : "Key map",
      value: section
    }));
  }, [activeSection]);
  const shortcutOptions = useMemo(() => {
    return SHORTCUTS.map((shortcut) => ({
      name: `${shortcut.id}. ${shortcut.label}`,
      description: shortcut.run || shortcut.template || "",
      value: shortcut.id
    }));
  }, []);
  const historyOptions = useMemo(() => {
    return entries.map((entry) => ({
      name: formatHistoryLabel(entry),
      description: new Date(entry.createdAt).toLocaleTimeString(),
      value: entry.id
    }));
  }, [entries]);
  const dataSourceOptions = useMemo(() => {
    return dataSourceRows.map((row) => {
      if (row.kind === "app") {
        const itemCount = dataSourceCountByAppKey.get(row.appKey) || 0;
        return {
          name: `${row.expanded ? "[-]" : "[+]"} ${row.appName}${row.appSlug ? ` (${row.appSlug})` : ""}`,
          description: `${itemCount} data source${itemCount === 1 ? "" : "s"}`,
          value: row.id
        };
      }
      const dataSourceLabel = row.dataSourceName || row.dataSourceSlug || row.dataSourceId || "Unknown";
      return {
        name: `  - ${dataSourceLabel}${row.dataSourceSlug ? ` (${row.dataSourceSlug})` : ""}`,
        description: row.appSlug ? `app: ${row.appSlug}` : "missing app slug",
        value: row.id
      };
    });
  }, [dataSourceCountByAppKey, dataSourceRows]);
  const renderLeftSection = () => {
    if (activeSection === "shortcuts") {
      return /* @__PURE__ */ jsx2(
        "select",
        {
          focused: focusedPanel === "left" && !isExitConfirmOpen && !isRunning,
          options: shortcutOptions,
          selectedIndex: selectedShortcutIndex,
          onChange: (index) => {
            setSelectedShortcutIndex(index);
          },
          onSelect: (index, option) => {
            setSelectedShortcutIndex(index);
            const shortcutId = Number(option?.value || 0);
            if (Number.isFinite(shortcutId) && shortcutId > 0) {
              applyShortcut(shortcutId);
            }
          },
          showScrollIndicator: true,
          style: {
            flexGrow: 1
          }
        }
      );
    }
    if (activeSection === "datasources") {
      const treeFocused = focusedPanel === "left" && dataSourcePanelFocus === "tree" && !isRunning && !isExitConfirmOpen;
      const searchFocused = focusedPanel === "left" && dataSourcePanelFocus === "search" && !isRunning && !isExitConfirmOpen;
      return /* @__PURE__ */ jsxs2("box", { flexDirection: "column", flexGrow: 1, children: [
        /* @__PURE__ */ jsx2("box", { border: true, borderStyle: "single", borderColor: searchFocused ? "#7aa2f7" : "#414868", paddingX: 1, children: /* @__PURE__ */ jsx2(
          "input",
          {
            value: dataSourceSearch,
            placeholder: "Search data sources...",
            onChange: (value) => {
              setDataSourceSearch(value);
              setSelectedDataSourceRowIndex(0);
            },
            onSubmit: () => {
              setDataSourcePanelFocus("tree");
            },
            focused: searchFocused,
            style: {
              flexGrow: 1
            }
          }
        ) }),
        /* @__PURE__ */ jsx2("box", { marginTop: 1, marginBottom: 1, children: /* @__PURE__ */ jsx2("text", { fg: "gray", children: "/ to search, Esc to tree, Space toggle app, Enter run ds get, r refresh" }) }),
        isCatalogLoading && /* @__PURE__ */ jsx2("text", { fg: "cyan", children: "Loading DataSources catalog..." }),
        catalogError && /* @__PURE__ */ jsx2("text", { fg: "red", children: catalogError }),
        dataSourceOptions.length === 0 ? /* @__PURE__ */ jsx2("text", { fg: "gray", children: dataSourceSearch.trim().length > 0 ? `No data sources match "${dataSourceSearch}".` : "No data sources available for this tenant." }) : /* @__PURE__ */ jsx2(
          "select",
          {
            focused: treeFocused,
            options: dataSourceOptions,
            selectedIndex: selectedDataSourceRowIndex,
            onChange: (index) => {
              setSelectedDataSourceRowIndex(index);
            },
            onSelect: (index) => {
              setSelectedDataSourceRowIndex(index);
              const row = dataSourceRows[index] || null;
              void runSelectedDataSourceRow(row);
            },
            showScrollIndicator: true,
            style: {
              flexGrow: 1
            }
          }
        )
      ] });
    }
    if (activeSection === "history") {
      if (entries.length === 0) {
        return /* @__PURE__ */ jsx2("text", { fg: "gray", children: "No command history yet." });
      }
      return /* @__PURE__ */ jsxs2("box", { flexDirection: "column", flexGrow: 1, children: [
        /* @__PURE__ */ jsx2("text", { fg: "cyan", children: "Press `r` to re-run selected command." }),
        /* @__PURE__ */ jsx2(
          "select",
          {
            focused: focusedPanel === "left" && !isExitConfirmOpen && !isRunning,
            options: historyOptions,
            selectedIndex: selectedHistoryIndex,
            onChange: (index, option) => {
              setSelectedHistoryIndex(index);
              if (typeof option?.value === "string") {
                setActiveEntryId(option.value);
              }
            },
            onSelect: (index, option) => {
              setSelectedHistoryIndex(index);
              if (typeof option?.value === "string") {
                setActiveEntryId(option.value);
              }
            },
            showScrollIndicator: true,
            style: {
              flexGrow: 1
            }
          }
        )
      ] });
    }
    if (activeSection === "messages") {
      return /* @__PURE__ */ jsxs2(
        "scrollbox",
        {
          ref: leftScrollRef,
          focused: focusedPanel === "left" && !isExitConfirmOpen && !isRunning,
          style: { height: "100%" },
          children: [
            systemMessages.length === 0 && /* @__PURE__ */ jsx2("text", { fg: "gray", children: "No messages yet." }),
            systemMessages.map((line, index) => /* @__PURE__ */ jsx2("text", { children: line }, `message-${index}`))
          ]
        }
      );
    }
    return /* @__PURE__ */ jsxs2(
      "scrollbox",
      {
        ref: leftScrollRef,
        focused: focusedPanel === "left" && !isExitConfirmOpen && !isRunning,
        style: { height: "100%" },
        children: [
          /* @__PURE__ */ jsx2("text", { fg: "cyan", children: "Key Bindings" }),
          /* @__PURE__ */ jsx2("text", { children: "Input Left/Right: caret move, edge switches panel" }),
          /* @__PURE__ */ jsx2("text", { children: "Left/Right (non-input/result): switch focused panel" }),
          /* @__PURE__ */ jsx2("text", { children: "Up/Down in left lists: selection" }),
          /* @__PURE__ */ jsx2("text", { children: "Up/Down in result: vertical scroll" }),
          /* @__PURE__ */ jsx2("text", { children: "Left/Right in result: horizontal scroll (edge switches panel)" }),
          /* @__PURE__ */ jsx2("text", { children: "Down at bottom in left/result: focus command input" }),
          /* @__PURE__ */ jsx2("text", { children: "Enter: run command" }),
          /* @__PURE__ */ jsx2("text", { children: "Up/Down in input: command history" }),
          /* @__PURE__ */ jsx2("text", { children: "Tab in result panel: toggle PRETTY/JSON" }),
          /* @__PURE__ */ jsx2("text", { children: "Tab / Shift+Tab (outside result): next/prev left section" }),
          /* @__PURE__ */ jsx2("text", { children: "[ / ]: next/prev left section" }),
          /* @__PURE__ */ jsx2("text", { children: "1..6: run shortcut" }),
          /* @__PURE__ */ jsx2("text", { children: "/ in DataSources: focus search" }),
          /* @__PURE__ */ jsx2("text", { children: "Esc in DataSources search: return to tree" }),
          /* @__PURE__ */ jsx2("text", { children: "Space in DataSources tree: toggle app folder" }),
          /* @__PURE__ */ jsx2("text", { children: "Enter in DataSources tree: run ds get or toggle app" }),
          /* @__PURE__ */ jsx2("text", { children: "Ctrl+L: clear command and message history" }),
          /* @__PURE__ */ jsx2("text", { children: "Esc (other panel): focus command input" }),
          /* @__PURE__ */ jsx2("text", { children: "Esc then Esc: open exit confirmation" }),
          /* @__PURE__ */ jsx2("text", { children: "Enter (confirm): exit, Esc (confirm): cancel" }),
          /* @__PURE__ */ jsx2("text", { children: "Ctrl+C: force quit" })
        ]
      }
    );
  };
  return /* @__PURE__ */ jsxs2("box", { flexDirection: "column", width: "100%", height: "100%", padding: 1, children: [
    /* @__PURE__ */ jsxs2("box", { flexDirection: "row", justifyContent: "space-between", marginBottom: 1, paddingX: 1, children: [
      /* @__PURE__ */ jsxs2(
        "box",
        {
          style: {
            position: "relative",
            width: 50,
            height: 6
          },
          children: [
            /* @__PURE__ */ jsx2(
              "box",
              {
                style: {
                  position: "absolute",
                  left: 1,
                  top: 0
                },
                children: /* @__PURE__ */ jsx2(
                  "ascii-font",
                  {
                    text: "DOCYRUS",
                    font: "block",
                    color: RGBA2.fromHex("#3f4bff")
                  }
                )
              }
            ),
            /* @__PURE__ */ jsx2(
              "box",
              {
                style: {
                  position: "absolute",
                  left: 0,
                  top: 0
                },
                children: /* @__PURE__ */ jsx2(
                  "ascii-font",
                  {
                    text: "DOCYRUS",
                    font: "block",
                    color: [
                      RGBA2.fromHex("#ef4444"),
                      RGBA2.fromHex("#ef4444")
                    ]
                  }
                )
              }
            )
          ]
        }
      ),
      /* @__PURE__ */ jsxs2("box", { flexDirection: "column", alignItems: "flex-end", justifyContent: "center", children: [
        /* @__PURE__ */ jsxs2("text", { children: [
          "env: ",
          environment ? `${environment.name} (${environment.id})` : "unknown"
        ] }),
        /* @__PURE__ */ jsxs2("text", { children: [
          "status: ",
          isRunning ? `${spinner} running` : isCatalogLoading ? `${spinner} loading-catalog` : "idle"
        ] }),
        /* @__PURE__ */ jsxs2("text", { children: [
          "account: ",
          context ? context.email : "not-authenticated"
        ] }),
        /* @__PURE__ */ jsxs2("text", { children: [
          "tenant: ",
          context ? context.tenantDisplay : "-"
        ] })
      ] })
    ] }),
    /* @__PURE__ */ jsxs2("box", { flexDirection: "row", flexGrow: 1, children: [
      /* @__PURE__ */ jsxs2(
        "box",
        {
          width: 46,
          marginRight: 1,
          border: true,
          borderStyle: "rounded",
          borderColor: focusedPanel === "left" ? "#7aa2f7" : "#3b4261",
          padding: 1,
          flexDirection: "column",
          children: [
            /* @__PURE__ */ jsx2(
              "tab-select",
              {
                focused: focusedPanel === "left" && !isExitConfirmOpen && !isRunning,
                options: sectionOptions,
                onChange: (_index, option) => {
                  if (typeof option?.value === "string") {
                    setActiveSection(option.value);
                    setDataSourcePanelFocus("tree");
                  }
                }
              }
            ),
            /* @__PURE__ */ jsx2("box", { marginTop: 1, flexGrow: 1, border: true, borderStyle: "single", borderColor: "#414868", padding: 1, children: renderLeftSection() })
          ]
        }
      ),
      /* @__PURE__ */ jsx2(
        "box",
        {
          border: true,
          borderStyle: "double",
          borderColor: focusedPanel === "result" ? "#9ece6a" : "#3b4261",
          padding: 1,
          flexGrow: 1,
          children: isRunning ? /* @__PURE__ */ jsxs2("box", { width: "100%", height: "100%", alignItems: "center", justifyContent: "center", flexDirection: "column", children: [
            /* @__PURE__ */ jsx2("text", { fg: "cyan", children: spinner }),
            /* @__PURE__ */ jsx2("text", { fg: "gray", children: "Running command..." })
          ] }) : renderResult({
            entry: activeEntry,
            isFocused: focusedPanel === "result" && !isExitConfirmOpen,
            viewMode: resultViewMode,
            onViewModeChange: setResultViewMode,
            resultScrollRef
          })
        }
      )
    ] }),
    /* @__PURE__ */ jsxs2(
      "box",
      {
        border: true,
        borderStyle: "rounded",
        borderColor: focusedPanel === "input" ? "#e0af68" : "#3b4261",
        padding: 1,
        marginTop: 1,
        children: [
          /* @__PURE__ */ jsx2("text", { fg: "cyan", children: "> " }),
          /* @__PURE__ */ jsx2(
            "input",
            {
              ref: commandInputRef,
              style: { flexGrow: 1 },
              value: input,
              placeholder: "Type a command...",
              onChange: (value) => {
                setInput(value);
              },
              onSubmit: (value) => {
                submitInput(typeof value === "string" ? value : void 0);
              },
              focused: !isRunning && !isCatalogLoading && focusedPanel === "input" && !isExitConfirmOpen
            }
          )
        ]
      }
    ),
    isExitConfirmOpen && /* @__PURE__ */ jsx2(
      "box",
      {
        style: {
          position: "absolute",
          top: 0,
          left: 0,
          width: "100%",
          height: "100%"
        },
        alignItems: "center",
        justifyContent: "center",
        children: /* @__PURE__ */ jsxs2(
          "box",
          {
            width: 58,
            padding: 1,
            border: true,
            borderStyle: "double",
            borderColor: "#f7768e",
            flexDirection: "column",
            style: {
              backgroundColor: "#1f2335"
            },
            children: [
              /* @__PURE__ */ jsx2("text", { fg: "#f7768e", children: "Exit Docyrus TUI?" }),
              /* @__PURE__ */ jsx2("text", { children: "Press Enter to exit." }),
              /* @__PURE__ */ jsx2("text", { children: "Press Esc to stay in this session." })
            ]
          }
        )
      }
    )
  ] });
}

// src/tui/opentuiMain.tsx
import { jsx as jsx3 } from "@opentui/react/jsx-runtime";
function readRequiredEnv(name) {
  const value = process.env[name];
  if (!value || value.trim().length === 0) {
    throw new Error(`Missing required launch variable: ${name}`);
  }
  return value;
}
function readLaunchConfig() {
  return {
    version: process.env.DOCYRUS_TUI_VERSION || "dev",
    executionConfig: {
      executable: readRequiredEnv("DOCYRUS_TUI_EXECUTABLE"),
      scriptPath: readRequiredEnv("DOCYRUS_TUI_SCRIPT")
    }
  };
}
async function startTui() {
  const launchConfig = readLaunchConfig();
  const renderer = await createCliRenderer({
    exitOnCtrlC: false
  });
  const root = createRoot(renderer);
  root.render(
    /* @__PURE__ */ jsx3(
      DocyrusOpenTuiApp,
      {
        executionConfig: launchConfig.executionConfig,
        version: launchConfig.version
      }
    )
  );
}
void startTui().catch((error) => {
  const message = error instanceof Error ? error.message : String(error);
  console.error(`Failed to start Docyrus OpenTUI: ${message}`);
  process.exitCode = 1;
});
//# sourceMappingURL=tui.mjs.map
