// Force strict mode and setup for ESM
"use strict";
import {
  getEffectiveSupportedModes
} from "./chunk-ZGPJFEEO.js";
import {
  require_jsx_runtime
} from "./chunk-OJINH4QS.js";
import {
  require_react
} from "./chunk-HTHUX2T5.js";
import {
  getCachedStringWidth
} from "./chunk-JZZFWHB3.js";
import {
  uiTelemetryService
} from "./chunk-D3DWHKLI.js";
import {
  init_esbuild_shims
} from "./chunk-5O2XNYP6.js";
import {
  __name,
  __toESM
} from "./chunk-J2S4EL5Y.js";

// packages/cli/src/ui/contexts/SessionContext.tsx
init_esbuild_shims();
var import_react = __toESM(require_react(), 1);
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
var EMPTY_SKILL_METRICS = {
  totalCalls: 0,
  totalSuccess: 0,
  totalFail: 0,
  byName: {}
};
function areModelMetricsCoreEqual(a, b) {
  if (a.api.totalRequests !== b.api.totalRequests || a.api.totalErrors !== b.api.totalErrors || a.api.totalLatencyMs !== b.api.totalLatencyMs) {
    return false;
  }
  if (a.tokens.prompt !== b.tokens.prompt || a.tokens.candidates !== b.tokens.candidates || a.tokens.total !== b.tokens.total || a.tokens.cached !== b.tokens.cached || a.tokens.thoughts !== b.tokens.thoughts) {
    return false;
  }
  return true;
}
__name(areModelMetricsCoreEqual, "areModelMetricsCoreEqual");
function areModelMetricsEqual(a, b) {
  if (!areModelMetricsCoreEqual(a, b)) return false;
  const aKeys = Object.keys(a.bySource);
  const bKeys = Object.keys(b.bySource);
  if (aKeys.length !== bKeys.length) return false;
  for (const key of aKeys) {
    const aSource = a.bySource[key];
    const bSource = b.bySource[key];
    if (!bSource || !areModelMetricsCoreEqual(aSource, bSource)) {
      return false;
    }
  }
  return true;
}
__name(areModelMetricsEqual, "areModelMetricsEqual");
function areToolCallStatsEqual(a, b) {
  if (a.count !== b.count || a.success !== b.success || a.fail !== b.fail || a.durationMs !== b.durationMs) {
    return false;
  }
  if (a.decisions["accept" /* ACCEPT */] !== b.decisions["accept" /* ACCEPT */] || a.decisions["reject" /* REJECT */] !== b.decisions["reject" /* REJECT */] || a.decisions["modify" /* MODIFY */] !== b.decisions["modify" /* MODIFY */] || a.decisions["auto_accept" /* AUTO_ACCEPT */] !== b.decisions["auto_accept" /* AUTO_ACCEPT */]) {
    return false;
  }
  return true;
}
__name(areToolCallStatsEqual, "areToolCallStatsEqual");
function areSkillCallStatsEqual(a, b) {
  return a.count === b.count && a.success === b.success && a.fail === b.fail;
}
__name(areSkillCallStatsEqual, "areSkillCallStatsEqual");
function areSkillMetricsEqual(a, b) {
  if (a.totalCalls !== b.totalCalls || a.totalSuccess !== b.totalSuccess || a.totalFail !== b.totalFail) {
    return false;
  }
  const aKeys = Object.keys(a.byName);
  const bKeys = Object.keys(b.byName);
  if (aKeys.length !== bKeys.length) return false;
  for (const key of aKeys) {
    const skillA = a.byName[key];
    const skillB = b.byName[key];
    if (!skillB || !areSkillCallStatsEqual(skillA, skillB)) {
      return false;
    }
  }
  return true;
}
__name(areSkillMetricsEqual, "areSkillMetricsEqual");
function areMetricsEqual(a, b) {
  if (a === b) return true;
  if (!a || !b) return false;
  if (a.files.totalLinesAdded !== b.files.totalLinesAdded || a.files.totalLinesRemoved !== b.files.totalLinesRemoved) {
    return false;
  }
  const toolsA = a.tools;
  const toolsB = b.tools;
  if (toolsA.totalCalls !== toolsB.totalCalls || toolsA.totalSuccess !== toolsB.totalSuccess || toolsA.totalFail !== toolsB.totalFail || toolsA.totalDurationMs !== toolsB.totalDurationMs) {
    return false;
  }
  if (toolsA.totalDecisions["accept" /* ACCEPT */] !== toolsB.totalDecisions["accept" /* ACCEPT */] || toolsA.totalDecisions["reject" /* REJECT */] !== toolsB.totalDecisions["reject" /* REJECT */] || toolsA.totalDecisions["modify" /* MODIFY */] !== toolsB.totalDecisions["modify" /* MODIFY */] || toolsA.totalDecisions["auto_accept" /* AUTO_ACCEPT */] !== toolsB.totalDecisions["auto_accept" /* AUTO_ACCEPT */]) {
    return false;
  }
  const toolsByNameAKeys = Object.keys(toolsA.byName);
  const toolsByNameBKeys = Object.keys(toolsB.byName);
  if (toolsByNameAKeys.length !== toolsByNameBKeys.length) return false;
  for (const key of toolsByNameAKeys) {
    const toolA = toolsA.byName[key];
    const toolB = toolsB.byName[key];
    if (!toolB || !areToolCallStatsEqual(toolA, toolB)) {
      return false;
    }
  }
  if (!areSkillMetricsEqual(
    a.skills ?? EMPTY_SKILL_METRICS,
    b.skills ?? EMPTY_SKILL_METRICS
  )) {
    return false;
  }
  const modelsAKeys = Object.keys(a.models);
  const modelsBKeys = Object.keys(b.models);
  if (modelsAKeys.length !== modelsBKeys.length) return false;
  for (const key of modelsAKeys) {
    if (!b.models[key] || !areModelMetricsEqual(a.models[key], b.models[key])) {
      return false;
    }
  }
  return true;
}
__name(areMetricsEqual, "areMetricsEqual");
function cloneSessionMetrics(metrics) {
  return {
    models: Object.fromEntries(
      Object.entries(metrics.models).map(([name, model]) => [
        name,
        {
          api: { ...model.api },
          tokens: { ...model.tokens },
          bySource: Object.fromEntries(
            Object.entries(model.bySource).map(([source, sourceMetrics]) => [
              source,
              {
                api: { ...sourceMetrics.api },
                tokens: { ...sourceMetrics.tokens }
              }
            ])
          )
        }
      ])
    ),
    tools: {
      totalCalls: metrics.tools.totalCalls,
      totalSuccess: metrics.tools.totalSuccess,
      totalFail: metrics.tools.totalFail,
      totalDurationMs: metrics.tools.totalDurationMs,
      totalDecisions: { ...metrics.tools.totalDecisions },
      byName: Object.fromEntries(
        Object.entries(metrics.tools.byName).map(([name, stats]) => [
          name,
          {
            count: stats.count,
            success: stats.success,
            fail: stats.fail,
            durationMs: stats.durationMs,
            decisions: { ...stats.decisions }
          }
        ])
      )
    },
    files: {
      totalLinesAdded: metrics.files.totalLinesAdded,
      totalLinesRemoved: metrics.files.totalLinesRemoved
    },
    ...metrics.skills ? {
      skills: {
        totalCalls: metrics.skills.totalCalls,
        totalSuccess: metrics.skills.totalSuccess,
        totalFail: metrics.skills.totalFail,
        byName: Object.fromEntries(
          Object.entries(metrics.skills.byName).map(([name, stats]) => [
            name,
            {
              count: stats.count,
              success: stats.success,
              fail: stats.fail
            }
          ])
        )
      }
    } : {}
  };
}
__name(cloneSessionMetrics, "cloneSessionMetrics");
function getMetricsForDisplay(sessionId) {
  return cloneSessionMetrics(
    sessionId ? uiTelemetryService.getMetricsForSession(sessionId) : uiTelemetryService.getMetrics()
  );
}
__name(getMetricsForDisplay, "getMetricsForDisplay");
var SessionStatsContext = (0, import_react.createContext)(
  void 0
);
var createDefaultStats = /* @__PURE__ */ __name((sessionId = "") => ({
  sessionId,
  sessionStartTime: /* @__PURE__ */ new Date(),
  metrics: getMetricsForDisplay(sessionId),
  lastPromptTokenCount: 0,
  promptCount: 0
}), "createDefaultStats");
var SessionStatsProvider = /* @__PURE__ */ __name(({ sessionId, children }) => {
  const [stats, setStats] = (0, import_react.useState)(
    () => createDefaultStats(sessionId ?? "")
  );
  (0, import_react.useEffect)(() => {
    const handleUpdate = /* @__PURE__ */ __name(({
      metrics,
      lastPromptTokenCount
    }) => {
      setStats((prevState) => {
        const nextMetrics = prevState.sessionId ? getMetricsForDisplay(prevState.sessionId) : cloneSessionMetrics(metrics);
        if (prevState.lastPromptTokenCount === lastPromptTokenCount && areMetricsEqual(prevState.metrics, nextMetrics)) {
          return prevState;
        }
        return {
          ...prevState,
          metrics: nextMetrics,
          lastPromptTokenCount
        };
      });
    }, "handleUpdate");
    uiTelemetryService.on("update", handleUpdate);
    handleUpdate({
      metrics: uiTelemetryService.getMetrics(),
      lastPromptTokenCount: uiTelemetryService.getLastPromptTokenCount()
    });
    return () => {
      uiTelemetryService.off("update", handleUpdate);
    };
  }, []);
  const startNewSession = (0, import_react.useCallback)((sessionId2) => {
    setStats(() => ({
      ...createDefaultStats(sessionId2),
      lastPromptTokenCount: uiTelemetryService.getLastPromptTokenCount()
    }));
  }, []);
  const startNewPrompt = (0, import_react.useCallback)(() => {
    setStats((prevState) => ({
      ...prevState,
      promptCount: prevState.promptCount + 1
    }));
  }, []);
  const getPromptCount = (0, import_react.useCallback)(
    () => stats.promptCount,
    [stats.promptCount]
  );
  const seedPromptCount = (0, import_react.useCallback)((count) => {
    setStats((prevState) => ({
      ...prevState,
      promptCount: Math.max(prevState.promptCount, count)
    }));
  }, []);
  const value = (0, import_react.useMemo)(
    () => ({
      stats,
      startNewSession,
      startNewPrompt,
      getPromptCount,
      seedPromptCount
    }),
    [stats, startNewSession, startNewPrompt, getPromptCount, seedPromptCount]
  );
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SessionStatsContext.Provider, { value, children });
}, "SessionStatsProvider");
var useSessionStats = /* @__PURE__ */ __name(() => {
  const context = (0, import_react.useContext)(SessionStatsContext);
  if (context === void 0) {
    throw new Error(
      "useSessionStats must be used within a SessionStatsProvider"
    );
  }
  return context;
}, "useSessionStats");

// packages/cli/src/services/commandMetadata.ts
init_esbuild_shims();
function getCommandSourceBadge(command) {
  switch (command.source) {
    case "bundled-skill":
      return "[Skill]";
    case "skill-dir-command":
      if (command.sourceDetail === "user") {
        return "[User]";
      }
      if (command.sourceDetail === "project") {
        return "[Project]";
      }
      return "[Custom]";
    case "plugin-command":
      return command.sourceDetail === "extension" ? "[Extension]" : "[Plugin]";
    case "mcp-prompt":
      return "[MCP]";
    case "builtin-command":
    default:
      return null;
  }
}
__name(getCommandSourceBadge, "getCommandSourceBadge");
function getCommandSourceGroup(command) {
  switch (command.source) {
    case "builtin-command":
      return { key: "built-in", title: "Built-in Commands", order: 0 };
    case "bundled-skill":
      return { key: "bundled-skill", title: "Bundled Skills", order: 1 };
    case "skill-dir-command":
      return { key: "custom", title: "Custom Commands", order: 2 };
    case "plugin-command":
      return { key: "plugin", title: "Plugin Commands", order: 3 };
    case "mcp-prompt":
      return { key: "mcp", title: "MCP Commands", order: 4 };
    default:
      return { key: "other", title: "Other Commands", order: 5 };
  }
}
__name(getCommandSourceGroup, "getCommandSourceGroup");
function formatSupportedModes(command) {
  const modes = getEffectiveSupportedModes(command);
  const hasInteractive = modes.includes("interactive");
  const hasNonInteractive = modes.includes("non_interactive");
  const hasAcp = modes.includes("acp");
  if (hasInteractive && hasNonInteractive && hasAcp) {
    return "[all]";
  }
  if (!hasInteractive && hasNonInteractive && hasAcp) {
    return "[headless]";
  }
  if (hasInteractive && !hasNonInteractive && !hasAcp) {
    return "[interactive]";
  }
  return modes.map((mode) => {
    switch (mode) {
      case "interactive":
        return "[i]";
      case "non_interactive":
        return "[ni]";
      case "acp":
        return "[acp]";
      default:
        return `[${mode}]`;
    }
  }).join(" ");
}
__name(formatSupportedModes, "formatSupportedModes");
function getCommandDisplayName(command, options = {}) {
  const prefix = options.prefix ?? "";
  const baseLabel = `${prefix}${command.name}`;
  if (options.matchedAlias) {
    return `${baseLabel} (alias: ${options.matchedAlias})`;
  }
  if (options.includeAliases === false) {
    return baseLabel;
  }
  const altNames = command.altNames?.filter(Boolean);
  if (!altNames || altNames.length === 0) {
    return baseLabel;
  }
  return `${baseLabel} (${altNames.join(", ")})`;
}
__name(getCommandDisplayName, "getCommandDisplayName");
function getCommandSubcommandNames(command) {
  return command.subCommands?.filter((subCommand) => !subCommand.hidden).map((subCommand) => subCommand.name) ?? [];
}
__name(getCommandSubcommandNames, "getCommandSubcommandNames");

// packages/cli/src/ui/utils/pending-rendered-height.ts
init_esbuild_shims();
var TABLE_CHROME_ROWS = 5;
var TABLE_MAX_ROW_LINES = 4;
var TABLE_ROW_RE = /^\s*\|(.+)\|\s*$/;
var TABLE_SEPARATOR_RE = /^(?=.*\|)\s*\|?\s*(:?-+:?)\s*(\|\s*(:?-+:?)\s*)*\|?\s*$/;
var CODE_FENCE_RE = /^ *(`{3,}|~{3,}) *([^`]*)$/;
var INLINE_MATH_MAX_CHARS = 1024;
var TABLE_INLINE_MATH_SPAN_RE = new RegExp(
  String.raw`(?<![\w$])\$(?![\s\d$])(?=[^$\n]{1,${INLINE_MATH_MAX_CHARS}}\S\$)[^$\n]{1,${INLINE_MATH_MAX_CHARS}}\$(?![\w$])`,
  "y"
);
function readTableInlineMathSpan(row, index) {
  TABLE_INLINE_MATH_SPAN_RE.lastIndex = index;
  return TABLE_INLINE_MATH_SPAN_RE.exec(row)?.[0] ?? null;
}
__name(readTableInlineMathSpan, "readTableInlineMathSpan");
function splitMarkdownTableRow(row) {
  const cells = [];
  let current = "";
  let activeCodeFenceLength = 0;
  for (let index = 0; index < row.length; index++) {
    const char = row[index];
    if (char === "\\") {
      const next = row[index + 1];
      if (next === "|") {
        current += "|";
        index += 1;
        continue;
      }
      current += char;
      continue;
    }
    if (char === "`") {
      let runLength = 1;
      while (row[index + runLength] === "`") {
        runLength += 1;
      }
      if (activeCodeFenceLength === 0) {
        activeCodeFenceLength = runLength;
      } else if (runLength === activeCodeFenceLength) {
        activeCodeFenceLength = 0;
      }
      current += "`".repeat(runLength);
      index += runLength - 1;
      continue;
    }
    if (char === "$" && activeCodeFenceLength === 0) {
      const mathSpan = readTableInlineMathSpan(row, index);
      if (mathSpan) {
        current += mathSpan;
        index += mathSpan.length - 1;
        continue;
      }
    }
    if (char === "|" && activeCodeFenceLength === 0) {
      cells.push(current.trim());
      current = "";
      continue;
    }
    current += char;
  }
  cells.push(current.trim());
  return cells;
}
__name(splitMarkdownTableRow, "splitMarkdownTableRow");
function estimateWrappedRows(line, width) {
  if (width <= 0) return 1;
  return Math.max(1, Math.ceil(getCachedStringWidth(line) / width));
}
__name(estimateWrappedRows, "estimateWrappedRows");
function isTableStart(lines, i) {
  const header = lines[i];
  if (header === void 0 || i + 1 >= lines.length) return false;
  const headerMatch = TABLE_ROW_RE.exec(header);
  if (!headerMatch) return false;
  const separator = lines[i + 1];
  if (!TABLE_SEPARATOR_RE.test(separator)) return false;
  const headerCols = splitMarkdownTableRow(headerMatch[1]).length;
  const sepCols = splitMarkdownTableRow(separator).filter(
    (cell) => cell.length > 0
  ).length;
  return headerCols === sepCols;
}
__name(isTableStart, "isTableStart");
function fitPendingSlice(allLines, contentWidth, budget, tableClampRows) {
  let rendered = 0;
  let kept = allLines.length;
  let codeFence = "";
  for (let i = 0; i < allLines.length; ) {
    const line = allLines[i];
    const fenceMatch = CODE_FENCE_RE.exec(line);
    if (codeFence) {
      if (fenceMatch && fenceMatch[1].startsWith(codeFence[0]) && fenceMatch[1].length >= codeFence.length) {
        codeFence = "";
      }
      rendered += estimateWrappedRows(line, contentWidth);
      if (rendered > budget) {
        kept = i;
        break;
      }
      i++;
      continue;
    }
    if (fenceMatch) {
      codeFence = fenceMatch[1];
      rendered += estimateWrappedRows(line, contentWidth);
      if (rendered > budget) {
        kept = i;
        break;
      }
      i++;
      continue;
    }
    if (isTableStart(allLines, i)) {
      let j = i + 2;
      while (j < allLines.length && TABLE_ROW_RE.test(allLines[j])) j++;
      const dataRows = j - (i + 2);
      const headerCells = splitMarkdownTableRow(
        TABLE_ROW_RE.exec(allLines[i])[1]
      );
      const colCount = headerCells.length;
      const minHorizontalWidth = Math.max(24, 6 * colCount + 5);
      const perColWidth = Math.max(
        3,
        Math.floor((contentWidth - (1 + 3 * colCount) - 4) / colCount)
      );
      let contentRows = 0;
      let verticalRows = 0;
      let maxRowLines = 1;
      for (const label of headerCells) {
        maxRowLines = Math.max(
          maxRowLines,
          estimateWrappedRows(label, perColWidth)
        );
      }
      contentRows += maxRowLines;
      for (let r = i + 2; r < j; r++) {
        const cells = splitMarkdownTableRow(
          TABLE_ROW_RE.exec(allLines[r])[1]
        );
        let rowMax = 1;
        for (let colIdx = 0; colIdx < cells.length; colIdx++) {
          const value = cells[colIdx];
          rowMax = Math.max(rowMax, estimateWrappedRows(value, perColWidth));
          const label = headerCells[colIdx] ?? "";
          verticalRows += estimateWrappedRows(
            label ? `${label}: ${value}` : value,
            contentWidth
          );
        }
        contentRows += rowMax;
        if (r === i + 2) {
          maxRowLines = Math.max(maxRowLines, rowMax);
        }
      }
      const usesVertical = dataRows > 0 && (contentWidth < minHorizontalWidth || maxRowLines > TABLE_MAX_ROW_LINES);
      const rows = usesVertical ? verticalRows + Math.max(0, dataRows - 1) + 2 : contentRows + Math.max(0, dataRows - 1) + TABLE_CHROME_ROWS;
      const cost = Math.min(rows, tableClampRows + 2);
      if (rendered + cost > budget && i > 0) {
        kept = i;
        break;
      }
      rendered += cost;
      i = j;
      if (rendered >= budget) {
        kept = j;
        break;
      }
    } else {
      rendered += estimateWrappedRows(line, contentWidth);
      if (rendered > budget) {
        kept = i;
        break;
      }
      i++;
    }
  }
  return { keptLines: kept, clipped: kept < allLines.length };
}
__name(fitPendingSlice, "fitPendingSlice");

export {
  TABLE_MAX_ROW_LINES,
  TABLE_ROW_RE,
  TABLE_SEPARATOR_RE,
  CODE_FENCE_RE,
  splitMarkdownTableRow,
  fitPendingSlice,
  SessionStatsProvider,
  useSessionStats,
  getCommandSourceBadge,
  getCommandSourceGroup,
  formatSupportedModes,
  getCommandDisplayName,
  getCommandSubcommandNames
};
/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2025 Qwen
 * SPDX-License-Identifier: Apache-2.0
 */
