// Force strict mode and setup for ESM
"use strict";
import {
  formatHistoryGapNotice,
  indexGapsByChild
} from "./chunk-2LLVTJVN.js";
import {
  sanitizeTerminalText
} from "./chunk-SUARMD4Q.js";
import {
  require_undici
} from "./chunk-L573Z2QZ.js";
import {
  writeStderrLine
} from "./chunk-YUZI3WAC.js";
import {
  getActiveGoal
} from "./chunk-KN5EBZLT.js";
import {
  apiActivityTracker,
  formatVisionBridgeNoticeDisplay,
  isVisionBridgeNoticeDisplay
} from "./chunk-D5K5YBSN.js";
import {
  ToolNames
} from "./chunk-JGUT3LWZ.js";
import {
  createDebugLogger
} from "./chunk-7NFB7LBQ.js";
import {
  init_esbuild_shims
} from "./chunk-5O2XNYP6.js";
import {
  __name,
  __toESM
} from "./chunk-J2S4EL5Y.js";

// packages/cli/src/services/setup-github.ts
init_esbuild_shims();
var import_undici2 = __toESM(require_undici(), 1);
import { promises as fsp } from "node:fs";
import * as path from "node:path";

// packages/cli/src/utils/gitUtils.ts
init_esbuild_shims();
var import_undici = __toESM(require_undici(), 1);
import * as childProcess from "node:child_process";
var debugLogger = createDebugLogger("GIT");
async function runGit(args, opts = {}) {
  return await new Promise((resolve2, reject) => {
    childProcess.execFile(
      "git",
      args,
      {
        encoding: "utf-8",
        ...opts.cwd ? { cwd: opts.cwd } : {}
      },
      (err, stdout) => {
        if (err) {
          reject(err);
          return;
        }
        resolve2(String(stdout ?? "").trim());
      }
    );
  });
}
__name(runGit, "runGit");
var isGitHubRepositoryAsync = /* @__PURE__ */ __name(async (opts = {}) => {
  try {
    const remotes = await runGit(["remote", "-v"], opts);
    return remotes.split("\n").some((line) => {
      const remoteUrl = line.trim().split(/\s+/)[1];
      return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
    });
  } catch (_error) {
    debugLogger.debug(`Failed to get git remote:`, _error);
    return false;
  }
}, "isGitHubRepositoryAsync");
function isGitHubRemoteUrl(remoteUrl) {
  if (remoteUrl.startsWith("git@github.com:")) {
    return true;
  }
  if (remoteUrl.startsWith("git@")) {
    return false;
  }
  try {
    return new URL(remoteUrl).hostname === "github.com";
  } catch {
    return false;
  }
}
__name(isGitHubRemoteUrl, "isGitHubRemoteUrl");
var getGitRepoRootAsync = /* @__PURE__ */ __name(async (opts = {}) => {
  const gitRepoRoot = await runGit(["rev-parse", "--show-toplevel"], opts);
  if (!gitRepoRoot) {
    throw new Error(`Git repo returned empty value`);
  }
  return gitRepoRoot;
}, "getGitRepoRootAsync");
var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
  try {
    const controller = new AbortController();
    const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
    const response = await fetch(endpoint, {
      method: "GET",
      headers: {
        Accept: "application/vnd.github+json",
        "Content-Type": "application/json",
        "X-GitHub-Api-Version": "2022-11-28"
      },
      dispatcher: proxy ? new import_undici.ProxyAgent(proxy) : void 0,
      signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
    });
    if (!response.ok) {
      throw new Error(
        `Invalid response code: ${response.status} - ${response.statusText}`
      );
    }
    const releaseTag = (await response.json()).tag_name;
    if (!releaseTag) {
      throw new Error(`Response did not include tag_name field`);
    }
    return releaseTag;
  } catch (_error) {
    debugLogger.debug(
      `Failed to determine latest qwen-code-action release:`,
      _error
    );
    throw new Error(
      `Unable to determine the latest qwen-code-action release on GitHub.`
    );
  }
}, "getLatestGitHubRelease");
async function getGitHubRepoInfoAsync(opts = {}) {
  return parseGitHubRepoInfo(
    await runGit(["remote", "get-url", "origin"], opts)
  );
}
__name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
function parseGitHubRepoInfo(remoteUrl) {
  let urlToParse = remoteUrl;
  if (remoteUrl.startsWith("git@github.com:")) {
    urlToParse = remoteUrl.replace("git@github.com:", "");
  } else if (remoteUrl.startsWith("git@")) {
    throw new Error(
      `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
    );
  }
  let parsedUrl;
  try {
    parsedUrl = new URL(urlToParse, "https://github.com");
  } catch {
    throw new Error(
      `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
    );
  }
  if (parsedUrl.hostname !== "github.com") {
    throw new Error(
      `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
    );
  }
  const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
    throw new Error(
      `Owner & repo could not be extracted from remote URL: ${remoteUrl}`
    );
  }
  return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
}
__name(parseGitHubRepoInfo, "parseGitHubRepoInfo");

// packages/cli/src/services/setup-github.ts
var debugLogger2 = createDebugLogger("SETUP_GITHUB");
var GITHUB_WORKFLOW_PATHS = [
  "qwen-dispatch/qwen-dispatch.yml",
  "qwen-assistant/qwen-invoke.yml",
  "issue-triage/qwen-triage.yml",
  "issue-triage/qwen-scheduled-triage.yml",
  "pr-review/qwen-review.yml"
];
var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
var SetupGithubError = class extends Error {
  static {
    __name(this, "SetupGithubError");
  }
  code;
  status;
  partial;
  partialResult;
  constructor(code, message, status, partialResult) {
    super(message);
    this.name = "SetupGithubError";
    this.code = code;
    this.status = status;
    this.partial = partialResult !== void 0;
    this.partialResult = partialResult;
  }
};
var nodeFileOps = {
  assertCanWrite() {
  },
  async ensureWorkflowDirectory(gitRepoRoot) {
    await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
      recursive: true
    });
  },
  async writeTextFile(gitRepoRoot, relativePath, content) {
    const target = path.join(gitRepoRoot, relativePath);
    await fsp.writeFile(target, content, { mode: 420 });
    return { sizeBytes: Buffer.byteLength(content, "utf8") };
  },
  async readTextFile(gitRepoRoot, relativePath) {
    try {
      return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
    } catch (error) {
      if (error.code === "ENOENT") {
        return void 0;
      }
      throw error;
    }
  }
};
async function setupGithub(options = {}) {
  const cwd = options.cwd ?? process.cwd();
  const fileOps = options.fileOps ?? nodeFileOps;
  if (!await isGitHubRepositoryAsync({ cwd })) {
    throw new SetupGithubError(
      "github_repository_not_found",
      "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
      400
    );
  }
  let gitRepoRoot;
  try {
    gitRepoRoot = await getGitRepoRootAsync({ cwd });
  } catch (error) {
    debugLogger2.debug("Failed to get git repo root:", error);
    throw new SetupGithubError(
      "github_repository_not_found",
      "Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
      400
    );
  }
  if (options.workspaceRoot) {
    const [gitRootReal, workspaceReal] = await Promise.all([
      realpathOrResolve(gitRepoRoot),
      realpathOrResolve(options.workspaceRoot)
    ]);
    if (gitRootReal !== workspaceReal) {
      throw new SetupGithubError(
        "github_git_root_mismatch",
        "The Git repository root must match the daemon workspace root.",
        400
      );
    }
  }
  fileOps.assertCanWrite?.();
  let releaseTag;
  try {
    releaseTag = await getLatestGitHubRelease(options.proxy);
  } catch (error) {
    writeStderrLine(
      `qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
    );
    debugLogger2.debug(
      "Failed to determine latest qwen-code-action release:",
      error
    );
    throw new SetupGithubError(
      "github_release_lookup_failed",
      "Unable to determine the latest qwen-code-action release on GitHub.",
      502
    );
  }
  const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
  const secretsUrl = await resolveSecretsUrl(cwd);
  const downloads = await downloadWorkflows({
    releaseTag,
    proxy: options.proxy,
    abortSignal: options.abortSignal,
    fetchImpl: options.fetchImpl ?? fetch
  });
  const result = {
    kind: "github_setup",
    workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
    gitRepoRoot,
    releaseTag,
    readmeUrl,
    ...secretsUrl ? { secretsUrl } : {},
    workflows: [],
    gitignore: { path: ".gitignore", status: "skipped" },
    warnings: []
  };
  result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
  if (result.gitignore.status === "failed") {
    result.warnings.push("Failed to update .gitignore.");
  }
  try {
    await fileOps.ensureWorkflowDirectory(gitRepoRoot);
    for (const workflow of downloads) {
      const relativePath = path.posix.join(
        ".github",
        "workflows",
        path.posix.basename(workflow.sourcePath)
      );
      try {
        const write = await fileOps.writeTextFile(
          gitRepoRoot,
          relativePath,
          workflow.content
        );
        result.workflows.push({
          sourcePath: workflow.sourcePath,
          path: relativePath,
          status: "written",
          sizeBytes: write.sizeBytes
        });
      } catch (error) {
        result.partial = true;
        result.workflows.push({
          sourcePath: workflow.sourcePath,
          path: relativePath,
          status: "failed",
          error: error instanceof Error ? error.message : String(error)
        });
        throw new SetupGithubError(
          "github_workflow_write_failed",
          `Unable to write ${relativePath}.`,
          500,
          result
        );
      }
    }
  } catch (error) {
    if (error instanceof SetupGithubError) throw error;
    throw new SetupGithubError(
      "github_workflow_write_failed",
      "Unable to create .github/workflows.",
      500,
      result
    );
  }
  return result;
}
__name(setupGithub, "setupGithub");
async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
  try {
    const existingContent = await fileOps.readTextFile(
      gitRepoRoot,
      ".gitignore"
    );
    if (existingContent === void 0) {
      const content = GITIGNORE_ENTRIES.join("\n") + "\n";
      await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
      return {
        path: ".gitignore",
        status: "created",
        added: [...GITIGNORE_ENTRIES]
      };
    }
    const missingEntries = GITIGNORE_ENTRIES.filter(
      (entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
    );
    if (missingEntries.length === 0) {
      return { path: ".gitignore", status: "unchanged" };
    }
    const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
    await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
    return {
      path: ".gitignore",
      status: "updated",
      added: missingEntries
    };
  } catch (error) {
    debugLogger2.debug("Failed to update .gitignore:", error);
    return {
      path: ".gitignore",
      status: "failed",
      error: error instanceof Error ? error.message : String(error)
    };
  }
}
__name(updateGitignore, "updateGitignore");
async function downloadWorkflows(options) {
  const internalAbort = new AbortController();
  try {
    const dispatcher = options.proxy ? new import_undici2.ProxyAgent(options.proxy) : void 0;
    return await Promise.all(
      GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
        const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
        const response = await options.fetchImpl(endpoint, {
          method: "GET",
          dispatcher,
          signal: AbortSignal.any([
            AbortSignal.timeout(3e4),
            internalAbort.signal,
            ...options.abortSignal ? [options.abortSignal] : []
          ])
        });
        if (!response.ok) {
          throw new Error(
            `Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
          );
        }
        return {
          sourcePath: workflow,
          content: await readResponseTextWithLimit(response, workflow)
        };
      })
    );
  } catch (error) {
    internalAbort.abort();
    const message = error instanceof Error ? error.message : String(error);
    debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
    throw new SetupGithubError(
      "github_workflow_download_failed",
      `Unable to download qwen-code-action workflows from GitHub. ${message}`,
      502
    );
  }
}
__name(downloadWorkflows, "downloadWorkflows");
async function readResponseTextWithLimit(response, sourcePath) {
  const contentLength = response.headers.get("content-length");
  if (contentLength !== null) {
    const parsedLength = Number(contentLength);
    if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
      throw new Error(
        `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
      );
    }
  }
  if (!response.body) return "";
  const reader = response.body.getReader();
  const chunks = [];
  let totalBytes = 0;
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      if (!value) continue;
      totalBytes += value.byteLength;
      if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
        await reader.cancel().catch(() => {
        });
        throw new Error(
          `${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
        );
      }
      chunks.push(value);
    }
  } finally {
    reader.releaseLock();
  }
  const body = new Uint8Array(totalBytes);
  let offset = 0;
  for (const chunk of chunks) {
    body.set(chunk, offset);
    offset += chunk.byteLength;
  }
  return new TextDecoder().decode(body);
}
__name(readResponseTextWithLimit, "readResponseTextWithLimit");
async function resolveSecretsUrl(cwd) {
  try {
    const repoInfo = await getGitHubRepoInfoAsync({ cwd });
    return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
  } catch {
    return void 0;
  }
}
__name(resolveSecretsUrl, "resolveSecretsUrl");
async function realpathOrResolve(input) {
  try {
    return await fsp.realpath(input);
  } catch {
    return path.resolve(input);
  }
}
__name(realpathOrResolve, "realpathOrResolve");

// packages/cli/src/acp-integration/session/emitters/MessageEmitter.ts
init_esbuild_shims();

// packages/cli/src/acp-integration/session/emitters/base-emitter.ts
init_esbuild_shims();
var BaseEmitter = class {
  constructor(ctx) {
    this.ctx = ctx;
  }
  static {
    __name(this, "BaseEmitter");
  }
  /**
   * Converts an ISO timestamp string or epoch ms to epoch ms number.
   * Returns undefined if the input is not a valid timestamp.
   */
  static toEpochMs(ts) {
    if (typeof ts === "number") {
      return Number.isFinite(ts) ? ts : void 0;
    }
    if (typeof ts === "string") {
      const ms = new Date(ts).getTime();
      return Number.isFinite(ms) ? ms : void 0;
    }
    return void 0;
  }
  /**
   * Sends a session update to the ACP client.
   * If a message rewriter is configured, updates pass through it first
   * (original messages are sent as-is, rewritten versions are appended).
   */
  async sendUpdate(update) {
    if (this.ctx.messageRewriter) {
      return this.ctx.messageRewriter.interceptUpdate(update);
    }
    return this.ctx.sendUpdate(update);
  }
  /**
   * Gets the session ID.
   */
  get sessionId() {
    return this.ctx.sessionId;
  }
};

// packages/cli/src/acp-integration/session/emitters/MessageEmitter.ts
var MessageEmitter = class extends BaseEmitter {
  static {
    __name(this, "MessageEmitter");
  }
  /**
   * Emits a StopHookLoop event when Stop hooks create a loop.
   * This informs the client that Stop hooks have been executed multiple times.
   *
   * @param iterationCount - The current iteration count
   * @param reasons - Array of reasons from each Stop hook execution
   * @param stopHookCount - Number of Stop hooks that were executed
   */
  async emitStopHookLoop(iterationCount, reasons, stopHookCount) {
    const activeGoal = getActiveGoal(this.sessionId);
    await this.sendUpdate({
      sessionUpdate: "agent_message_chunk",
      content: { type: "text", text: "" },
      _meta: {
        stopHookLoop: {
          iterationCount,
          reasons,
          stopHookCount,
          ...activeGoal ? {
            goal: {
              condition: activeGoal.condition,
              iterations: activeGoal.iterations,
              setAt: activeGoal.setAt,
              lastReason: activeGoal.lastReason
            }
          } : {}
        }
      }
    });
  }
  async emitGoalTerminal(event) {
    await this.sendUpdate({
      sessionUpdate: "agent_message_chunk",
      content: { type: "text", text: "" },
      _meta: {
        goalTerminal: event
      }
    });
  }
  async emitGoalStatus(status) {
    await this.sendUpdate({
      sessionUpdate: "agent_message_chunk",
      content: { type: "text", text: "" },
      _meta: {
        goalStatus: status
      }
    });
  }
  /**
   * Emits a user message chunk.
   *
   * @param text - The user message text content
   * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
   */
  async emitUserMessage(text, timestamp, options = {}) {
    const epochMs = BaseEmitter.toEpochMs(timestamp);
    const _meta = {
      ...epochMs != null ? { timestamp: epochMs } : {},
      ...options.source ? { source: options.source } : {}
    };
    await this.sendUpdate({
      sessionUpdate: "user_message_chunk",
      content: { type: "text", text },
      ...Object.keys(_meta).length > 0 ? { _meta } : {}
    });
  }
  /**
   * Emits an agent thought chunk.
   *
   * @param text - The thought text content
   * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
   */
  async emitAgentThought(text, timestamp, subagentMeta) {
    const _meta = this.buildChunkMeta(
      BaseEmitter.toEpochMs(timestamp),
      subagentMeta
    );
    await this.sendUpdate({
      sessionUpdate: "agent_thought_chunk",
      content: { type: "text", text },
      ..._meta ? { _meta } : {}
    });
  }
  /**
   * Emits an agent message chunk.
   *
   * @param text - The agent message text content
   * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
   */
  async emitAgentMessage(text, timestamp, subagentMeta) {
    const _meta = this.buildChunkMeta(
      BaseEmitter.toEpochMs(timestamp),
      subagentMeta
    );
    await this.sendUpdate({
      sessionUpdate: "agent_message_chunk",
      content: { type: "text", text },
      ..._meta ? { _meta } : {}
    });
  }
  async emitSlashCommandOutput(text, timestamp) {
    const epochMs = BaseEmitter.toEpochMs(timestamp);
    await this.sendUpdate({
      sessionUpdate: "agent_message_chunk",
      content: { type: "text", text },
      _meta: {
        source: "slash_command",
        ...epochMs != null ? { timestamp: epochMs } : {}
      }
    });
  }
  /**
   * Emits usage metadata.
   */
  async emitUsageMetadata(usageMetadata, text = "", durationMs, subagentMeta) {
    const usage = {
      inputTokens: usageMetadata.promptTokenCount ?? 0,
      outputTokens: usageMetadata.candidatesTokenCount ?? 0,
      totalTokens: usageMetadata.totalTokenCount ?? 0,
      thoughtTokens: usageMetadata.thoughtsTokenCount,
      cachedReadTokens: usageMetadata.cachedContentTokenCount
    };
    const cumulative = this.ctx.cumulativeUsage;
    if (cumulative) {
      const addFinite = /* @__PURE__ */ __name((total, value) => typeof value === "number" && Number.isFinite(value) ? total + value : total, "addFinite");
      cumulative.promptTokens = addFinite(
        cumulative.promptTokens,
        usage.inputTokens
      );
      cumulative.candidateTokens = addFinite(
        cumulative.candidateTokens,
        usage.outputTokens
      );
      cumulative.cachedTokens = addFinite(
        cumulative.cachedTokens,
        usage.cachedReadTokens
      );
      cumulative.apiTimeMs = addFinite(cumulative.apiTimeMs, durationMs);
    }
    let meta;
    if (typeof durationMs === "number") {
      const activity = apiActivityTracker.drain();
      meta = {
        usage,
        durationMs,
        ...activity.errors > 0 ? { apiErrors: activity.errors } : {},
        ...activity.retries > 0 ? { apiRetries: activity.retries } : {},
        ...subagentMeta
      };
    } else {
      meta = { usage, ...subagentMeta };
    }
    await this.sendUpdate({
      sessionUpdate: "agent_message_chunk",
      content: { type: "text", text },
      _meta: meta
    });
  }
  /**
   * Emits a message chunk based on role and thought flag.
   * This is the unified method that handles all message types.
   *
   * @param text - The message text content
   * @param role - Whether this is a user or assistant message
   * @param isThought - Whether this is an assistant thought (only applies to assistant role)
   * @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
   */
  async emitMessage(text, role, isThought = false, timestamp, subagentMeta) {
    if (role === "user") {
      return this.emitUserMessage(text, timestamp);
    }
    return isThought ? this.emitAgentThought(text, timestamp, subagentMeta) : this.emitAgentMessage(text, timestamp, subagentMeta);
  }
  buildChunkMeta(epochMs, subagentMeta) {
    const meta = {
      ...subagentMeta?.parentToolCallId ? { parentToolCallId: subagentMeta.parentToolCallId } : {},
      ...subagentMeta?.subagentType ? { subagentType: subagentMeta.subagentType } : {},
      ...epochMs != null ? { timestamp: epochMs } : {}
    };
    return Object.keys(meta).length > 0 ? meta : void 0;
  }
};

// packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
init_esbuild_shims();
var PlanEmitter = class extends BaseEmitter {
  static {
    __name(this, "PlanEmitter");
  }
  /**
   * Emits a plan update with the given todo items.
   *
   * @param todos - Array of todo items to send as plan entries
   */
  async emitPlan(todos) {
    const entries = todos.map((todo) => ({
      content: todo.content,
      priority: "medium",
      // Default priority since todos don't have priority
      status: todo.status
    }));
    const cumulative = this.ctx.cumulativeUsage;
    await this.sendUpdate({
      sessionUpdate: "plan",
      entries,
      ...cumulative ? { _meta: { stats: { ...cumulative } } } : {}
    });
  }
  /**
   * Extracts todos from tool result display or args.
   * Tries multiple sources in priority order:
   * 1. Result display object with type 'todo_list'
   * 2. Result display as JSON string
   * 3. Args with 'todos' array
   *
   * @param resultDisplay - The tool result display (object, string, or undefined)
   * @param args - The tool call arguments (fallback source)
   * @returns Array of todos if found, null otherwise
   */
  extractTodos(resultDisplay, args) {
    const fromDisplay = this.extractFromResultDisplay(resultDisplay);
    if (fromDisplay) return fromDisplay;
    if (args && Array.isArray(args["todos"])) {
      return args["todos"];
    }
    return null;
  }
  /**
   * Extracts todos from a result display value.
   * Handles both object and JSON string formats.
   */
  extractFromResultDisplay(resultDisplay) {
    if (!resultDisplay) return null;
    if (typeof resultDisplay === "object") {
      const obj = resultDisplay;
      if (obj["type"] === "todo_list" && Array.isArray(obj["todos"])) {
        return obj["todos"];
      }
    }
    if (typeof resultDisplay === "string") {
      try {
        const parsed = JSON.parse(resultDisplay);
        if (parsed?.["type"] === "todo_list" && Array.isArray(parsed["todos"])) {
          return parsed["todos"];
        }
      } catch {
      }
    }
    return null;
  }
};

// packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
init_esbuild_shims();

// packages/cli/src/acp-integration/session/types.ts
init_esbuild_shims();
function hasFullSessionContext(context) {
  return "config" in context;
}
__name(hasFullSessionContext, "hasFullSessionContext");

// packages/cli/src/utils/truncatedDiffPreview.ts
init_esbuild_shims();
function buildTruncatedDiffPreviewText(display) {
  const fileName = typeof display["fileName"] === "string" ? display["fileName"] : "the edited file";
  const fileDiffLength = typeof display["fileDiffLength"] === "number" ? ` Original fileDiff length: ${display["fileDiffLength"]} chars.` : "";
  if (display["fileDiffTruncated"] === true) {
    return `Full diff omitted from saved session history for ${fileName}.${fileDiffLength}`;
  }
  return `Saved session preview only for ${fileName}; full original and new file contents are unavailable.`;
}
__name(buildTruncatedDiffPreviewText, "buildTruncatedDiffPreviewText");

// packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
var KIND_MAP = {
  ["read" /* Read */]: "read",
  ["edit" /* Edit */]: "edit",
  ["delete" /* Delete */]: "delete",
  ["move" /* Move */]: "move",
  ["search" /* Search */]: "search",
  ["execute" /* Execute */]: "execute",
  ["think" /* Think */]: "think",
  ["fetch" /* Fetch */]: "fetch",
  // ACP defines no 'agent' ToolKind (verified through @agentclientprotocol/sdk
  // 0.25.1). The daemon's ClientSideConnection Zod-validates every session/update
  // and session/request_permission from the `qwen --acp` child before fanning out
  // to SSE clients, so emitting 'agent' is rejected at that hop and the frame is
  // dropped. Map the internal Kind.Agent to 'other' on the wire to stay
  // protocol-valid; dedicated agent UI is delivered out-of-band (via _meta.toolName)
  // in a follow-up rather than via a kind the protocol can't carry.
  ["agent" /* Agent */]: "other",
  ["other" /* Other */]: "other"
};
var ToolCallEmitter = class _ToolCallEmitter extends BaseEmitter {
  static {
    __name(this, "ToolCallEmitter");
  }
  planEmitter;
  preparedCallIds = /* @__PURE__ */ new Set();
  constructor(ctx) {
    super(ctx);
    this.planEmitter = new PlanEmitter(ctx);
  }
  /**
   * Emits a tool call start event.
   *
   * @param params - Tool call start parameters
   * @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
   */
  async emitStart(params) {
    if (this.isTodoWriteTool(params.toolName)) {
      return false;
    }
    if (params.phase === "preparing" && this.preparedCallIds.has(params.callId)) {
      return false;
    }
    const { title, locations, kind } = this.resolveToolMetadata(
      params.toolName,
      params.args
    );
    const provenance = _ToolCallEmitter.resolveToolProvenance(
      params.toolName,
      params.subagentMeta
    );
    const updatesPreparedCall = params.phase !== "preparing" && this.preparedCallIds.delete(params.callId);
    const update = {
      toolCallId: params.callId,
      status: params.status || "pending",
      title,
      content: [],
      locations,
      kind,
      rawInput: params.args ?? {},
      _meta: {
        toolName: params.toolName,
        ...params.phase ? { phase: params.phase } : {},
        ...params.subagentMeta,
        provenance: provenance.provenance,
        ...provenance.serverId ? { serverId: provenance.serverId } : {},
        ...BaseEmitter.toEpochMs(params.timestamp) != null && {
          timestamp: BaseEmitter.toEpochMs(params.timestamp)
        }
      }
    };
    await this.sendUpdate(
      updatesPreparedCall ? { sessionUpdate: "tool_call_update", ...update } : { sessionUpdate: "tool_call", ...update }
    );
    if (params.phase === "preparing") {
      this.preparedCallIds.add(params.callId);
    }
    return true;
  }
  /**
   * Emits a terminal frame when a prepared tool call is discarded before
   * execution. TodoWrite remains represented exclusively by plan updates.
   *
   * @param callId - ID of the prepared tool call
   * @param toolName - Name of the prepared tool
   */
  async emitPreparationDiscarded(callId, toolName) {
    if (this.isTodoWriteTool(toolName)) return;
    this.preparedCallIds.delete(callId);
    const provenance = _ToolCallEmitter.resolveToolProvenance(toolName);
    await this.sendUpdate({
      sessionUpdate: "tool_call_update",
      toolCallId: callId,
      status: "failed",
      content: [],
      _meta: {
        toolName,
        phase: "preparing",
        preparationDiscarded: true,
        provenance: provenance.provenance,
        ...provenance.serverId ? { serverId: provenance.serverId } : {}
      }
    });
  }
  /**
   * Emits a tool call result event.
   * Handles TodoWriteTool specially by routing to plan updates.
   *
   * @param params - Tool call result parameters
   */
  async emitResult(params) {
    if (this.isTodoWriteTool(params.toolName)) {
      const todos = this.planEmitter.extractTodos(
        params.resultDisplay,
        params.args
      );
      if (todos && todos.length > 0) {
        await this.planEmitter.emitPlan(todos);
      } else if (params.args && Array.isArray(params.args["todos"])) {
        await this.planEmitter.emitPlan([]);
      }
      return;
    }
    this.preparedCallIds.delete(params.callId);
    let contentArray = [];
    const diffContent = this.extractDiffContent(params.resultDisplay);
    if (diffContent) {
      contentArray = [diffContent];
    } else if (params.error) {
      contentArray = [
        {
          type: "content",
          content: { type: "text", text: params.error.message }
        }
      ];
    } else {
      contentArray = this.transformPartsToToolCallContent(params.message);
    }
    if (isVisionBridgeNoticeDisplay(params.resultDisplay)) {
      contentArray.unshift({
        type: "content",
        content: {
          type: "text",
          text: sanitizeTerminalText(
            formatVisionBridgeNoticeDisplay(params.resultDisplay)
          )
        }
      });
    }
    const provenance = _ToolCallEmitter.resolveToolProvenance(
      params.toolName,
      params.subagentMeta
    );
    const update = {
      sessionUpdate: "tool_call_update",
      toolCallId: params.callId,
      status: params.success ? "completed" : "failed",
      content: contentArray,
      _meta: {
        toolName: params.toolName,
        ...params.subagentMeta,
        provenance: provenance.provenance,
        ...provenance.serverId ? { serverId: provenance.serverId } : {},
        ...BaseEmitter.toEpochMs(params.timestamp) != null && {
          timestamp: BaseEmitter.toEpochMs(params.timestamp)
        },
        ...params.artifacts && params.artifacts.length > 0 ? { artifacts: params.artifacts } : {}
      }
    };
    if (params.resultDisplay !== void 0 && !this.isTruncatedSessionDiffDisplay(params.resultDisplay)) {
      update["rawOutput"] = params.resultDisplay;
    }
    await this.sendUpdate(update);
  }
  /**
   * Emits a tool call error event.
   * Use this for explicit error handling when not using emitResult.
   *
   * @param callId - The tool call ID
   * @param toolName - The tool name
   * @param error - The error that occurred
   * @param subagentMeta - Optional subagent metadata
   */
  async emitError(callId, toolName, error, subagentMeta) {
    this.preparedCallIds.delete(callId);
    const provenance = _ToolCallEmitter.resolveToolProvenance(
      toolName,
      subagentMeta
    );
    await this.sendUpdate({
      sessionUpdate: "tool_call_update",
      toolCallId: callId,
      status: "failed",
      content: [
        { type: "content", content: { type: "text", text: error.message } }
      ],
      _meta: {
        toolName,
        ...subagentMeta,
        provenance: provenance.provenance,
        ...provenance.serverId ? { serverId: provenance.serverId } : {}
      }
    });
  }
  /**
   * Resolve a tool's provenance for UI dispatch on tool_call events.
   * The SDK reads `_meta.
   * provenance` + `_meta.serverId` to render builtin / MCP-server-badge /
   * subagent-block differently. Without this stamping, the SDK falls
   * back to string-matching the toolName which can't reliably
   * distinguish builtin from subagent.
   *
   * Resolution rules:
   *   - `subagentMeta` present → `'subagent'` (a Task tool / Codex
   *     subagent / etc. wrapping its own tool calls)
   *   - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
   *     `serverId: <server>`. Naming convention from
   *     `packages/core/src/tools/mcp-tool.ts` in the
   *     `@qwen-code/qwen-code-core` package — mirrors the SDK's same
   *     heuristic fallback so SDK consumers stay consistent with
   *     daemon classification.
   *   - everything else → `'builtin'`
   *
   * Static + pure so it can be unit-tested without an emitter
   * instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
   */
  static resolveToolProvenance(toolName, subagentMeta) {
    if (subagentMeta !== void 0) {
      return { provenance: "subagent" };
    }
    if (toolName.startsWith("mcp__")) {
      const parts = toolName.split("__");
      if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
        return { provenance: "mcp", serverId: parts[1] };
      }
    }
    return { provenance: "builtin" };
  }
  // ==================== Public Utilities ====================
  /**
   * Checks if a tool name is the TodoWriteTool.
   * Exposed for external use in components that need to check this.
   */
  isTodoWriteTool(toolName) {
    return toolName === ToolNames.TODO_WRITE;
  }
  /**
   * Checks if a tool name is the ExitPlanModeTool.
   */
  isExitPlanModeTool(toolName) {
    return toolName === ToolNames.EXIT_PLAN_MODE;
  }
  /**
   * Checks if a tool name is the EnterPlanModeTool.
   */
  isEnterPlanModeTool(toolName) {
    return toolName === ToolNames.ENTER_PLAN_MODE;
  }
  /**
   * Resolves tool metadata from the registry.
   * Falls back to defaults if tool not found or build fails.
   *
   * @param toolName - Name of the tool
   * @param args - Tool call arguments (used to build invocation)
   */
  resolveToolMetadata(toolName, args) {
    if (!hasFullSessionContext(this.ctx)) {
      const description = typeof args?.["description"] === "string" ? args["description"].trim() : "";
      return {
        title: description ? `${toolName}: ${description}` : toolName,
        locations: [],
        kind: "other"
      };
    }
    const toolRegistry = this.ctx.config.getToolRegistry();
    const tool = toolRegistry.getTool(toolName);
    let title = tool?.displayName ?? toolName;
    let locations = [];
    let kind = "other";
    if (tool && args) {
      try {
        const invocation = tool.build(args);
        title = `${title}: ${invocation.getDescription()}`;
        locations = invocation.toolLocations().map((loc) => ({
          path: loc.path,
          line: loc.line ?? null
        }));
        kind = this.mapToolKind(tool.kind, toolName);
      } catch {
        if (typeof args["description"] === "string") {
          title = `${title}: ${args["description"]}`;
        }
        if (tool.kind) {
          kind = this.mapToolKind(tool.kind, toolName);
        }
      }
    }
    return { title, locations, kind };
  }
  /**
   * Maps core Tool Kind enum to ACP ToolKind string literals.
   *
   * @param kind - The core Kind enum value
   * @param toolName - Optional tool name to handle special cases like exit_plan_mode
   */
  mapToolKind(kind, toolName) {
    if (toolName && (this.isExitPlanModeTool(toolName) || this.isEnterPlanModeTool(toolName))) {
      return "switch_mode";
    }
    return KIND_MAP[kind] ?? "other";
  }
  // ==================== Private Helpers ====================
  /**
   * Extracts diff content from resultDisplay if it's a diff type (edit tool result).
   * Returns null if not a diff.
   */
  extractDiffContent(resultDisplay) {
    if (!resultDisplay || typeof resultDisplay !== "object") return null;
    const obj = resultDisplay;
    if ("fileName" in obj && "newContent" in obj) {
      if (this.isTruncatedSessionDiffDisplay(resultDisplay)) {
        return {
          type: "content",
          content: {
            type: "text",
            text: buildTruncatedDiffPreviewText(obj)
          }
        };
      }
      return {
        type: "diff",
        path: obj["fileName"],
        oldText: obj["originalContent"] ?? "",
        newText: obj["newContent"]
      };
    }
    return null;
  }
  isTruncatedSessionDiffDisplay(resultDisplay) {
    if (!resultDisplay || typeof resultDisplay !== "object") return false;
    const obj = resultDisplay;
    return obj["truncatedForSession"] === true && "fileName" in obj && "newContent" in obj;
  }
  /**
   * Transforms Part[] to ToolCallContent[].
   * Extracts text from functionResponse parts and text parts.
   */
  transformPartsToToolCallContent(parts) {
    const result = [];
    for (const part of parts) {
      if ("text" in part && part.text) {
        result.push({
          type: "content",
          content: { type: "text", text: part.text }
        });
      }
      if ("functionResponse" in part && part.functionResponse) {
        try {
          const resp = part.functionResponse.response;
          const outputField = resp["output"];
          const errorField = resp["error"];
          const responseText = typeof outputField === "string" ? outputField : typeof errorField === "string" ? errorField : JSON.stringify(resp);
          result.push({
            type: "content",
            content: { type: "text", text: responseText }
          });
        } catch {
        }
      }
    }
    return result;
  }
};

// packages/cli/src/acp-integration/session/history-replayer.ts
init_esbuild_shims();

// packages/cli/src/utils/chat-record-tool-call-id.ts
init_esbuild_shims();
function getToolResultCallId(record) {
  return getExplicitToolResultCallId(record) ?? record.uuid;
}
__name(getToolResultCallId, "getToolResultCallId");
function getExplicitToolResultCallId(record) {
  const resultCallId = record.toolCallResult?.callId;
  if (typeof resultCallId === "string" && resultCallId.length > 0) {
    return resultCallId;
  }
  return extractFunctionResponseId(record);
}
__name(getExplicitToolResultCallId, "getExplicitToolResultCallId");
function extractFunctionResponseId(record) {
  if (!record.message?.parts) {
    return void 0;
  }
  for (const part of record.message.parts) {
    const id = "functionResponse" in part ? part.functionResponse?.id : void 0;
    if (typeof id === "string" && id.length > 0) {
      return id;
    }
  }
  return void 0;
}
__name(extractFunctionResponseId, "extractFunctionResponseId");

// packages/cli/src/acp-integration/session/history-replayer.ts
var MISSING_TOOL_RESULT_MESSAGE = "Tool result missing from saved history; the previous run likely ended before this tool completed.";
var HistoryReplayer = class {
  static {
    __name(this, "HistoryReplayer");
  }
  ctx;
  messageEmitter;
  toolCallEmitter;
  pendingReplayToolCalls = /* @__PURE__ */ new Map();
  constructor(ctx) {
    this.ctx = ctx;
    this.messageEmitter = new MessageEmitter(ctx);
    this.toolCallEmitter = new ToolCallEmitter(ctx);
  }
  /**
   * Replays all chat records from a loaded session.
   *
   * @param records - Array of chat records to replay
   * @param gaps - Optional detected history gaps; a visible notice is emitted
   *   immediately before each gap's child record so the user sees that an
   *   earlier segment was lost rather than assuming the halves are contiguous.
   */
  async replay(records, gaps) {
    try {
      await this.replayPage(records, { finalizeDangling: true, gaps });
    } finally {
      this.pendingReplayToolCalls.clear();
      this.setActiveRecordId(null);
    }
  }
  async replayPage(records, options = {}) {
    this.pendingReplayToolCalls.clear();
    for (const pending of options.pendingToolCalls ?? []) {
      this.pendingReplayToolCalls.set(pending.callId, pending);
    }
    const gapByChildUuid = indexGapsByChild(options.gaps);
    let replayError;
    try {
      for (const record of records) {
        const gap = gapByChildUuid.get(record.uuid);
        if (gap) {
          await this.emitHistoryGapNotice(gap, record.timestamp);
        }
        await this.replayRecord(record);
      }
    } catch (error) {
      replayError = error;
    }
    let danglingError;
    if (options.finalizeDangling === true) {
      try {
        await this.failDanglingToolCalls();
      } catch (error) {
        danglingError = error;
      }
    }
    const state = {
      pendingToolCalls: options.finalizeDangling === true ? [] : Array.from(this.pendingReplayToolCalls.values())
    };
    this.setActiveRecordId(null);
    if (replayError && danglingError) {
      throw new AggregateError(
        [replayError, danglingError],
        "Replay and dangling-cleanup both failed"
      );
    }
    if (replayError) {
      throw replayError;
    }
    if (danglingError) {
      throw danglingError;
    }
    return state;
  }
  getPendingToolCalls() {
    return Array.from(this.pendingReplayToolCalls.values());
  }
  /**
   * Replays a single chat record.
   */
  async replayRecord(record) {
    this.setActiveRecordId(record.uuid, record.timestamp);
    try {
      switch (record.type) {
        case "user":
          if (record.subtype === "notification" || record.subtype === "cron") {
            const displayText = record.systemPayload?.displayText;
            if (displayText) {
              await this.messageEmitter.emitUserMessage(
                displayText,
                record.timestamp,
                record.subtype === "cron" ? { source: "cron" } : void 0
              );
            }
            break;
          }
          if (record.subtype === "mid_turn_user_message") {
            const displayText = record.systemPayload?.displayText;
            if (displayText) {
              await this.messageEmitter.emitUserMessage(
                displayText,
                record.timestamp
              );
            } else if (record.message) {
              await this.replayContent(
                record.message,
                "user",
                record.timestamp,
                record.uuid
              );
            }
            break;
          }
          if (record.message) {
            await this.replayContent(
              record.message,
              "user",
              record.timestamp,
              record.uuid
            );
          }
          break;
        case "assistant":
          if (record.message) {
            await this.replayContent(
              record.message,
              "assistant",
              record.timestamp,
              record.uuid
            );
          }
          if (record.usageMetadata) {
            await this.replayUsageMetadata(record.usageMetadata);
          }
          break;
        case "tool_result":
          await this.replayToolResult(record);
          break;
        case "system":
          if (record.subtype === "slash_command") {
            await this.replaySlashCommandResult(record);
          }
          break;
        default:
          break;
      }
    } finally {
      this.setActiveRecordId(null);
    }
  }
  /**
   * Emits a visible notice marking a break in the persisted history chain: an
   * earlier segment was physically lost (storage interruption) and could not be
   * recovered, so the surviving turns below must not be read as contiguous with
   * whatever came before the gap. Uses the agent message channel — the same one
   * used for other system notices (see MessageEmitter.emitStopHookLoop) — so no
   * new session-update kind is needed.
   */
  async emitHistoryGapNotice(gap, timestamp) {
    await this.messageEmitter.emitAgentMessage(
      formatHistoryGapNotice(gap),
      timestamp
    );
  }
  /**
   * Replays content from a message (user or assistant).
   * Handles text parts, thought parts, and function calls.
   *
   * @param content - The content to replay
   * @param role - The role (user or assistant)
   * @param timestamp - Optional server-side timestamp from the JSONL record
   */
  async replayContent(content, role, timestamp, recordId) {
    for (const part of content.parts ?? []) {
      if ("text" in part && part.text) {
        const isThought = part.thought ?? false;
        await this.messageEmitter.emitMessage(
          part.text,
          role,
          isThought,
          timestamp
        );
      }
      if ("functionCall" in part && part.functionCall) {
        const functionName = part.functionCall.name ?? "";
        const sourceCallId = part.functionCall.id;
        const callId = sourceCallId ?? `${functionName}-${Date.now()}`;
        const emitted = await this.toolCallEmitter.emitStart({
          toolName: functionName,
          callId,
          args: part.functionCall.args,
          status: "in_progress",
          timestamp
        });
        if (emitted && role === "assistant" && recordId && sourceCallId) {
          this.pendingReplayToolCalls.set(callId, {
            callId,
            toolName: functionName,
            timestamp,
            recordId
          });
        }
      }
    }
  }
  /**
   * Replays usage metadata.
   * @param usageMetadata - The usage metadata to replay
   */
  async replayUsageMetadata(usageMetadata) {
    await this.messageEmitter.emitUsageMetadata(usageMetadata);
  }
  /**
   * Replays a tool result record.
   */
  async replayToolResult(record) {
    if (!record.message?.parts) {
      return;
    }
    const result = record.toolCallResult;
    const callId = getToolResultCallId(record);
    this.pendingReplayToolCalls.delete(callId);
    const toolName = this.extractToolNameFromRecord(record);
    await this.toolCallEmitter.emitResult({
      toolName,
      callId,
      success: result?.status === void 0 ? !result?.error : result.status === "success" && !result.error,
      message: record.message.parts,
      resultDisplay: result?.resultDisplay,
      artifacts: result?.artifacts,
      // For TodoWriteTool fallback, try to extract args from the record
      // Note: args aren't stored in tool_result records by default
      args: void 0,
      timestamp: record.timestamp
    });
    const { resultDisplay } = result ?? {};
    if (!!resultDisplay && typeof resultDisplay === "object" && "type" in resultDisplay && resultDisplay.type === "task_execution") {
      await this.emitTaskUsageFromResultDisplay(
        resultDisplay
      );
    }
  }
  async failDanglingToolCalls() {
    let firstError;
    for (const pending of this.pendingReplayToolCalls.values()) {
      this.setActiveRecordId(pending.recordId, pending.timestamp);
      try {
        await this.toolCallEmitter.emitResult({
          toolName: pending.toolName,
          callId: pending.callId,
          success: false,
          message: [],
          error: new Error(MISSING_TOOL_RESULT_MESSAGE),
          timestamp: pending.timestamp
        });
      } catch (error) {
        firstError ??= error;
      } finally {
        this.setActiveRecordId(null);
      }
    }
    if (firstError) {
      throw firstError;
    }
  }
  /**
   * Emits token usage from a AgentResultDisplay execution summary, if present.
   */
  async emitTaskUsageFromResultDisplay(resultDisplay) {
    const summary = resultDisplay.executionSummary;
    if (!summary) {
      return;
    }
    const usageMetadata = {};
    if (Number.isFinite(summary.inputTokens)) {
      usageMetadata.promptTokenCount = summary.inputTokens;
    }
    if (Number.isFinite(summary.outputTokens)) {
      usageMetadata.candidatesTokenCount = summary.outputTokens;
    }
    if (Number.isFinite(summary.thoughtTokens)) {
      usageMetadata.thoughtsTokenCount = summary.thoughtTokens;
    }
    if (Number.isFinite(summary.cachedTokens)) {
      usageMetadata.cachedContentTokenCount = summary.cachedTokens;
    }
    if (Number.isFinite(summary.totalTokens)) {
      usageMetadata.totalTokenCount = summary.totalTokens;
    }
    if (Object.keys(usageMetadata).length > 0) {
      await this.messageEmitter.emitUsageMetadata(usageMetadata);
    }
  }
  /**
   * Replays a slash_command system record by re-emitting its output as an
   * agent message chunk. This allows Zed to reconstruct the correct turn
   * structure (user → agent) on session resume without polluting model context.
   */
  async replaySlashCommandResult(record) {
    const payload = record.systemPayload;
    if (payload?.phase !== "result" || !payload.outputHistoryItems?.length) {
      return;
    }
    for (const item of payload.outputHistoryItems) {
      const text = typeof item["text"] === "string" ? item["text"] : "";
      if (text) {
        await this.messageEmitter.emitSlashCommandOutput(
          text.replace(/\n/g, "  \n"),
          record.timestamp
        );
      }
    }
  }
  /**
   * Extracts tool name from a chat record's function response.
   */
  extractToolNameFromRecord(record) {
    if (record.message?.parts) {
      for (const part of record.message.parts) {
        if ("functionResponse" in part && part.functionResponse?.name) {
          return part.functionResponse.name;
        }
      }
    }
    return "";
  }
  setActiveRecordId(recordId, timestamp) {
    const context = this.ctx;
    if (typeof context.setActiveRecordId === "function") {
      context.setActiveRecordId(recordId, timestamp);
    }
  }
};

// packages/cli/src/ui/utils/export/collect.ts
init_esbuild_shims();
import { randomUUID } from "node:crypto";
function extractToolNameFromRecord(record) {
  if (!record.message?.parts) {
    return void 0;
  }
  for (const part of record.message.parts) {
    if ("functionResponse" in part && part.functionResponse?.name) {
      return part.functionResponse.name;
    }
  }
  return void 0;
}
__name(extractToolNameFromRecord, "extractToolNameFromRecord");
function normalizeFunctionCallArgs(args) {
  if (args && typeof args === "object") {
    return args;
  }
  if (typeof args === "string") {
    try {
      const parsed = JSON.parse(args);
      if (parsed && typeof parsed === "object") {
        return parsed;
      }
    } catch {
    }
  }
  return void 0;
}
__name(normalizeFunctionCallArgs, "normalizeFunctionCallArgs");
function buildToolCallArgsIndex(records) {
  const byId = /* @__PURE__ */ new Map();
  const byName = /* @__PURE__ */ new Map();
  for (const record of records) {
    if (record.type !== "assistant" || !record.message?.parts) continue;
    for (const part of record.message.parts) {
      if (!("functionCall" in part) || !part.functionCall?.name) continue;
      const normalizedArgs = normalizeFunctionCallArgs(part.functionCall.args);
      if (!normalizedArgs) continue;
      const toolName = part.functionCall.name;
      const callId = typeof part.functionCall.id === "string" ? part.functionCall.id : null;
      if (callId) {
        byId.set(callId, normalizedArgs);
      }
      const queue = byName.get(toolName) ?? [];
      queue.push(normalizedArgs);
      byName.set(toolName, queue);
    }
  }
  return { byId, byName };
}
__name(buildToolCallArgsIndex, "buildToolCallArgsIndex");
function calculateFileStats(records) {
  const argsIndex = buildToolCallArgsIndex(records);
  const byNameCursor = /* @__PURE__ */ new Map();
  const stats = {
    filesWritten: 0,
    linesAdded: 0,
    linesRemoved: 0,
    writtenFilePaths: /* @__PURE__ */ new Set()
  };
  for (const record of records) {
    if (record.type !== "tool_result" || !record.toolCallResult) continue;
    const toolName = extractToolNameFromRecord(record);
    const callId = getExplicitToolResultCallId(record);
    const argsFromId = callId && argsIndex.byId.has(callId) ? argsIndex.byId.get(callId) : void 0;
    let args = argsFromId;
    if (!args && toolName) {
      const queue = argsIndex.byName.get(toolName);
      if (queue && queue.length > 0) {
        const cursor = byNameCursor.get(toolName) ?? 0;
        args = queue[cursor];
        byNameCursor.set(toolName, cursor + 1);
      }
    }
    const { resultDisplay } = record.toolCallResult;
    if (resultDisplay && typeof resultDisplay === "object" && "fileName" in resultDisplay) {
      const display = resultDisplay;
      const hasOriginalContent = "originalContent" in display;
      const hasNewContent = "newContent" in display;
      let filePath;
      if (typeof display.fileName === "string") {
        filePath = args?.["file_path"] || display.fileName;
      } else {
        filePath = "unknown";
      }
      if (hasOriginalContent || hasNewContent) {
        stats.filesWritten++;
        stats.writtenFilePaths.add(filePath);
        if (display.diffStat) {
          stats.linesAdded += display.diffStat.model_added_lines ?? 0;
          stats.linesRemoved += display.diffStat.model_removed_lines ?? 0;
        } else if (!display.truncatedForSession) {
          const oldText = String(display.originalContent ?? "");
          const newText = String(display.newContent ?? "");
          const oldLines = oldText.split("\n").filter((line) => line.length > 0).length;
          const newLines = newText.split("\n").filter((line) => line.length > 0).length;
          stats.linesAdded += newLines;
          stats.linesRemoved += oldLines;
        }
      }
    }
  }
  return stats;
}
__name(calculateFileStats, "calculateFileStats");
function extractTaskToolTokens(record) {
  if (record.type !== "tool_result" || !record.toolCallResult?.resultDisplay) {
    return 0;
  }
  const { resultDisplay } = record.toolCallResult;
  if (typeof resultDisplay === "object" && "type" in resultDisplay && resultDisplay.type === "task_execution" && "executionSummary" in resultDisplay) {
    const summary = resultDisplay.executionSummary;
    if (typeof summary.totalTokens === "number") {
      return summary.totalTokens;
    }
    return (summary.inputTokens ?? 0) + (summary.outputTokens ?? 0) + (summary.thoughtTokens ?? 0) + (summary.cachedTokens ?? 0);
  }
  return 0;
}
__name(extractTaskToolTokens, "extractTaskToolTokens");
function calculateTokenStats(records) {
  let totalTokens = 0;
  let lastValidRecord = null;
  for (const record of records) {
    if (record.type === "assistant") {
      if (record.usageMetadata) {
        totalTokens += record.usageMetadata.totalTokenCount ?? 0;
      }
      if (record.usageMetadata?.totalTokenCount !== void 0 && record.contextWindowSize !== void 0) {
        lastValidRecord = {
          totalTokenCount: record.usageMetadata.totalTokenCount,
          contextWindowSize: record.contextWindowSize
        };
      }
    }
    const taskTokens = extractTaskToolTokens(record);
    if (taskTokens > 0) {
      totalTokens += taskTokens;
    }
  }
  if (lastValidRecord) {
    const percent = lastValidRecord.totalTokenCount / lastValidRecord.contextWindowSize * 100;
    return {
      totalTokens,
      contextUsagePercent: Math.round(percent * 10) / 10,
      contextWindowSize: lastValidRecord.contextWindowSize
    };
  }
  const lastAssistantRecord = [...records].reverse().find((r) => r.type === "assistant" && r.contextWindowSize !== void 0);
  return {
    totalTokens,
    contextWindowSize: lastAssistantRecord?.contextWindowSize
  };
}
__name(calculateTokenStats, "calculateTokenStats");
function createExportSessionConfig(config) {
  const supportedConfig = {
    ...config,
    getToolRegistry: /* @__PURE__ */ __name(() => {
      const registry = config.getToolRegistry?.();
      return {
        getTool: /* @__PURE__ */ __name((toolName) => registry?.getTool?.(toolName) ?? null, "getTool")
      };
    }, "getToolRegistry")
  };
  return new Proxy(supportedConfig, {
    get(target, prop, receiver) {
      if (prop in target) {
        return Reflect.get(target, prop, receiver);
      }
      if (typeof prop === "symbol") {
        return void 0;
      }
      throw new Error(
        `Export session replay config does not implement ${prop}`
      );
    }
  });
}
__name(createExportSessionConfig, "createExportSessionConfig");
async function extractMetadata(conversation, config) {
  const { sessionId, startTime, messages } = conversation;
  const firstRecord = messages[0];
  const cwd = firstRecord?.cwd ?? "";
  const gitBranch = firstRecord?.gitBranch;
  let gitRepo;
  if (cwd) {
    const { getGitRepoName } = await import("./src-O6NJAI32.js");
    gitRepo = getGitRepoName(cwd);
  }
  let model;
  for (const record of messages) {
    if (record.type === "assistant" && record.model) {
      model = record.model;
      break;
    }
  }
  const channel = config.getChannel?.();
  const promptCount = messages.filter((m) => m.type === "user").length;
  const fileStats = calculateFileStats(messages);
  const tokenStats = calculateTokenStats(messages);
  return {
    sessionId,
    startTime,
    exportTime: (/* @__PURE__ */ new Date()).toISOString(),
    cwd,
    gitRepo,
    gitBranch,
    model,
    channel,
    promptCount,
    contextUsagePercent: tokenStats.contextUsagePercent,
    contextWindowSize: tokenStats.contextWindowSize,
    totalTokens: tokenStats.totalTokens,
    filesWritten: fileStats.writtenFilePaths.size,
    linesAdded: fileStats.linesAdded,
    linesRemoved: fileStats.linesRemoved,
    uniqueFiles: Array.from(fileStats.writtenFilePaths)
  };
}
__name(extractMetadata, "extractMetadata");
var ExportSessionContext = class {
  static {
    __name(this, "ExportSessionContext");
  }
  sessionId;
  config;
  messages = [];
  currentMessage = null;
  activeRecordId = null;
  activeRecordTimestamp = null;
  toolCallMap = /* @__PURE__ */ new Map();
  constructor(sessionId, config) {
    this.sessionId = sessionId;
    this.config = createExportSessionConfig(config);
  }
  async sendUpdate(update) {
    switch (update.sessionUpdate) {
      case "user_message_chunk":
        this.handleMessageChunk("user", update.content);
        break;
      case "agent_message_chunk": {
        const usageMeta = update._meta;
        const usageMetadata = usageMeta?.usage ? {
          promptTokenCount: usageMeta.usage.inputTokens,
          candidatesTokenCount: usageMeta.usage.outputTokens,
          totalTokenCount: usageMeta.usage.totalTokens,
          thoughtsTokenCount: usageMeta.usage.thoughtTokens,
          cachedContentTokenCount: usageMeta.usage.cachedReadTokens
        } : void 0;
        this.handleMessageChunk(
          "assistant",
          update.content,
          "assistant",
          usageMetadata
        );
        break;
      }
      case "agent_thought_chunk":
        this.handleMessageChunk("assistant", update.content, "thinking");
        break;
      case "tool_call":
        this.flushCurrentMessage();
        this.handleToolCallStart(update);
        break;
      case "tool_call_update":
        this.handleToolCallUpdate(update);
        break;
      case "plan":
        this.flushCurrentMessage();
        this.handlePlanUpdate(update);
        break;
      default:
        break;
    }
  }
  setActiveRecordId(recordId, timestamp) {
    this.activeRecordId = recordId;
    this.activeRecordTimestamp = timestamp ?? null;
  }
  getMessageTimestamp() {
    return this.activeRecordTimestamp ?? (/* @__PURE__ */ new Date()).toISOString();
  }
  getMessageUuid() {
    return this.activeRecordId ?? randomUUID();
  }
  handleMessageChunk(role, content, messageRole = role, usageMetadata) {
    if (content.type !== "text" || !content.text) return;
    if (this.currentMessage && (this.currentMessage.type !== role || this.currentMessage.role !== messageRole)) {
      this.flushCurrentMessage();
    }
    if (this.currentMessage && this.currentMessage.type === role && this.currentMessage.role === messageRole) {
      this.currentMessage.parts.push({ text: content.text });
      if (usageMetadata && role === "assistant") {
        this.currentMessage.usageMetadata = usageMetadata;
      }
    } else {
      this.currentMessage = {
        type: role,
        role: messageRole,
        parts: [{ text: content.text }],
        timestamp: Date.now(),
        ...usageMetadata && role === "assistant" ? { usageMetadata } : {}
      };
    }
  }
  handleToolCallStart(update) {
    const toolCall = {
      toolCallId: update.toolCallId,
      kind: update.kind || "other",
      title: typeof update.title === "string" ? update.title : update.title || "",
      status: update.status || "pending",
      rawInput: update.rawInput,
      locations: update.locations,
      timestamp: Date.now()
    };
    this.toolCallMap.set(update.toolCallId, toolCall);
    const uuid = this.getMessageUuid();
    this.messages.push({
      uuid,
      sessionId: this.sessionId,
      timestamp: this.getMessageTimestamp(),
      type: "tool_call",
      toolCall
    });
  }
  handleToolCallUpdate(update) {
    const toolCall = this.toolCallMap.get(update.toolCallId);
    if (toolCall) {
      if (update.status) toolCall.status = update.status;
      if (update.content) toolCall.content = update.content;
      if (update.title)
        toolCall.title = typeof update.title === "string" ? update.title : "";
    }
  }
  handlePlanUpdate(update) {
    const uuid = this.getMessageUuid();
    const timestamp = this.getMessageTimestamp();
    const todoText = update.entries.map((entry) => {
      const checkbox = entry.status === "completed" ? "[x]" : entry.status === "in_progress" ? "[-]" : "[ ]";
      return `- ${checkbox} ${entry.content}`;
    }).join("\n");
    const todoContent = [
      {
        type: "content",
        content: {
          type: "text",
          text: todoText
        }
      }
    ];
    this.messages.push({
      uuid,
      sessionId: this.sessionId,
      timestamp,
      type: "tool_call",
      toolCall: {
        toolCallId: uuid,
        // Use the same uuid as toolCallId for plan updates
        kind: "todowrite",
        title: "TodoList",
        status: "completed",
        content: todoContent,
        timestamp: Date.parse(timestamp)
      }
    });
  }
  flushCurrentMessage() {
    if (!this.currentMessage) return;
    const uuid = this.getMessageUuid();
    const exportMessage = {
      uuid,
      sessionId: this.sessionId,
      timestamp: this.getMessageTimestamp(),
      type: this.currentMessage.type,
      message: {
        role: this.currentMessage.role,
        parts: this.currentMessage.parts
      }
    };
    if (this.currentMessage.type === "assistant" && this.currentMessage.usageMetadata) {
      exportMessage.usageMetadata = this.currentMessage.usageMetadata;
    }
    this.messages.push(exportMessage);
    this.currentMessage = null;
  }
  flushMessages() {
    this.flushCurrentMessage();
  }
  getMessages() {
    return this.messages;
  }
};
async function collectSessionData(conversation, config) {
  const exportContext = new ExportSessionContext(
    conversation.sessionId,
    config
  );
  const replayer = new HistoryReplayer(exportContext);
  await replayer.replay(conversation.messages);
  exportContext.flushMessages();
  const messages = exportContext.getMessages();
  const metadata = await extractMetadata(conversation, config);
  return {
    sessionId: conversation.sessionId,
    startTime: conversation.startTime,
    messages,
    metadata
  };
}
__name(collectSessionData, "collectSessionData");

// packages/cli/src/ui/utils/export/normalize.ts
init_esbuild_shims();
function normalizeSessionData(sessionData, originalRecords, config) {
  const normalized = [...sessionData.messages];
  const toolCallIndexById = /* @__PURE__ */ new Map();
  normalized.forEach((message, index) => {
    if (message.type === "tool_call" && message.toolCall?.toolCallId) {
      toolCallIndexById.set(message.toolCall.toolCallId, index);
    }
  });
  const assistantMessageIndexByUuid = /* @__PURE__ */ new Map();
  normalized.forEach((message, index) => {
    if (message.type === "assistant") {
      assistantMessageIndexByUuid.set(message.uuid, index);
    }
  });
  for (const record of originalRecords) {
    if (record.type !== "tool_result") continue;
    const toolCallMessage = buildToolCallMessageFromResult(record, config);
    if (!toolCallMessage?.toolCall) continue;
    const existingIndex = toolCallIndexById.get(
      toolCallMessage.toolCall.toolCallId
    );
    if (existingIndex === void 0) {
      toolCallIndexById.set(
        toolCallMessage.toolCall.toolCallId,
        normalized.length
      );
      normalized.push(toolCallMessage);
      continue;
    }
    const existingMessage = normalized[existingIndex];
    if (existingMessage.type !== "tool_call" || !existingMessage.toolCall) {
      continue;
    }
    mergeToolCallData(existingMessage.toolCall, toolCallMessage.toolCall);
  }
  for (const record of originalRecords) {
    if (record.type !== "assistant") continue;
    if (!record.usageMetadata) continue;
    const existingIndex = assistantMessageIndexByUuid.get(record.uuid);
    if (existingIndex !== void 0) {
      if (!normalized[existingIndex].usageMetadata) {
        normalized[existingIndex].usageMetadata = record.usageMetadata;
      }
    }
  }
  return {
    ...sessionData,
    messages: normalized
  };
}
__name(normalizeSessionData, "normalizeSessionData");
function mergeToolCallData(existing, incoming) {
  if (!existing.content || existing.content.length === 0) {
    existing.content = incoming.content;
  }
  if (existing.status === "pending" || existing.status === "in_progress") {
    existing.status = incoming.status;
  }
  if (!existing.rawInput && incoming.rawInput) {
    existing.rawInput = incoming.rawInput;
  }
  if (!existing.kind || existing.kind === "other") {
    existing.kind = incoming.kind;
  }
  if ((!existing.title || existing.title === "") && incoming.title) {
    existing.title = incoming.title;
  }
  if ((!existing.locations || existing.locations.length === 0) && incoming.locations && incoming.locations.length > 0) {
    existing.locations = incoming.locations;
  }
}
__name(mergeToolCallData, "mergeToolCallData");
function buildToolCallMessageFromResult(record, config) {
  const toolCallResult = record.toolCallResult;
  const toolName = extractToolNameFromRecord2(record);
  if (toolName === ToolNames.TODO_WRITE) {
    return null;
  }
  const toolCallId = getToolResultCallId(record);
  const functionCallArgs = extractFunctionCallArgs(record);
  const { kind, title, locations } = resolveToolMetadata(
    config,
    toolName,
    functionCallArgs ?? toolCallResult?.args
  );
  const rawInput = normalizeRawInput(
    functionCallArgs ?? toolCallResult?.args
  );
  const resultContent = extractDiffContent(toolCallResult?.resultDisplay) ?? transformPartsToToolCallContent(record.message?.parts ?? []);
  const content = isVisionBridgeNoticeDisplay(toolCallResult?.resultDisplay) ? [
    {
      type: "content",
      content: {
        type: "text",
        text: sanitizeTerminalText(
          formatVisionBridgeNoticeDisplay(toolCallResult.resultDisplay)
        )
      }
    },
    ...resultContent
  ] : resultContent;
  return {
    uuid: record.uuid,
    parentUuid: record.parentUuid,
    sessionId: record.sessionId,
    timestamp: record.timestamp,
    type: "tool_call",
    toolCall: {
      toolCallId,
      kind,
      title,
      status: toolCallResult?.error ? "failed" : "completed",
      rawInput,
      content,
      locations,
      timestamp: Date.parse(record.timestamp)
    }
  };
}
__name(buildToolCallMessageFromResult, "buildToolCallMessageFromResult");
function extractToolNameFromRecord2(record) {
  if (!record.message?.parts) {
    return "";
  }
  for (const part of record.message.parts) {
    if ("functionResponse" in part && part.functionResponse?.name) {
      return part.functionResponse.name;
    }
  }
  return "";
}
__name(extractToolNameFromRecord2, "extractToolNameFromRecord");
function extractFunctionCallArgs(record) {
  if (!record.message?.parts) {
    return void 0;
  }
  for (const part of record.message.parts) {
    if ("functionCall" in part && part.functionCall?.args) {
      return part.functionCall.args;
    }
  }
  return void 0;
}
__name(extractFunctionCallArgs, "extractFunctionCallArgs");
function resolveToolMetadata(config, toolName, args) {
  const toolRegistry = config.getToolRegistry?.();
  const tool = toolName ? toolRegistry?.getTool?.(toolName) : void 0;
  let title = tool?.displayName ?? toolName ?? "tool_call";
  let locations;
  const kind = mapToolKind(tool?.kind, toolName);
  if (tool?.build && args) {
    try {
      const invocation = tool.build(args);
      title = `${title}: ${invocation.getDescription()}`;
      locations = invocation.toolLocations().map((loc) => ({
        path: loc.path,
        line: loc.line ?? null
      }));
    } catch {
    }
  }
  return { kind, title, locations };
}
__name(resolveToolMetadata, "resolveToolMetadata");
function mapToolKind(kind, toolName) {
  if (toolName && (toolName === ToolNames.EXIT_PLAN_MODE || toolName === ToolNames.ENTER_PLAN_MODE)) {
    return "switch_mode";
  }
  if (toolName && toolName === ToolNames.TODO_WRITE) {
    return "todowrite";
  }
  const allowedKinds = /* @__PURE__ */ new Set([
    "read",
    "edit",
    "delete",
    "move",
    "search",
    "execute",
    "think",
    "fetch",
    "other"
  ]);
  if (kind && allowedKinds.has(kind)) {
    return kind;
  }
  return "other";
}
__name(mapToolKind, "mapToolKind");
function extractDiffContent(resultDisplay) {
  if (!resultDisplay || typeof resultDisplay !== "object") {
    return null;
  }
  const display = resultDisplay;
  if ("fileName" in display && "newContent" in display) {
    if (display["truncatedForSession"] === true) {
      return [
        {
          type: "content",
          content: {
            type: "text",
            text: buildTruncatedDiffPreviewText(display)
          }
        }
      ];
    }
    return [
      {
        type: "diff",
        path: display["fileName"],
        oldText: display["originalContent"] ?? "",
        newText: display["newContent"]
      }
    ];
  }
  return null;
}
__name(extractDiffContent, "extractDiffContent");
function normalizeRawInput(value) {
  if (typeof value === "string") return value;
  if (typeof value === "object" && value !== null) return value;
  return void 0;
}
__name(normalizeRawInput, "normalizeRawInput");
function transformPartsToToolCallContent(parts) {
  const content = [];
  for (const part of parts) {
    if ("text" in part && part.text) {
      content.push({
        type: "content",
        content: { type: "text", text: part.text }
      });
      continue;
    }
    if ("functionResponse" in part && part.functionResponse) {
      const response = part.functionResponse.response;
      const outputField = response?.["output"];
      const errorField = response?.["error"];
      const responseText = typeof outputField === "string" ? outputField : typeof errorField === "string" ? errorField : JSON.stringify(response);
      content.push({
        type: "content",
        content: { type: "text", text: responseText }
      });
    }
  }
  return content;
}
__name(transformPartsToToolCallContent, "transformPartsToToolCallContent");

// packages/cli/src/ui/utils/export/formatters/markdown.ts
init_esbuild_shims();
function toMarkdown(sessionData) {
  const lines = [];
  const metadata = sessionData.metadata;
  lines.push("# Chat Session Export\n");
  lines.push(`- **Session ID**: \`${sanitizeText(sessionData.sessionId)}\``);
  lines.push(`- **Start Time**: ${sanitizeText(sessionData.startTime)}`);
  lines.push(
    `- **Exported**: ${sanitizeText(metadata?.exportTime ?? (/* @__PURE__ */ new Date()).toISOString())}`
  );
  lines.push("");
  if (metadata?.cwd) {
    lines.push(`- **Working Directory**: \`${sanitizeText(metadata.cwd)}\``);
  }
  if (metadata?.gitRepo) {
    lines.push(`- **Git Repository**: ${sanitizeText(metadata.gitRepo)}`);
  }
  if (metadata?.gitBranch) {
    lines.push(`- **Git Branch**: \`${sanitizeText(metadata.gitBranch)}\``);
  }
  lines.push("");
  if (metadata?.model) {
    lines.push(`- **Model**: ${sanitizeText(metadata.model)}`);
  }
  if (metadata?.channel) {
    lines.push(`- **Channel**: ${sanitizeText(metadata.channel)}`);
  }
  if (metadata?.promptCount !== void 0) {
    lines.push(`- **Prompt Count**: ${metadata.promptCount}`);
  }
  lines.push("");
  if (metadata?.totalTokens !== void 0) {
    lines.push(`- **Total Tokens**: ${metadata.totalTokens}`);
  }
  if (metadata?.contextWindowSize !== void 0) {
    lines.push(`- **Context Window Size**: ${metadata.contextWindowSize}`);
  }
  if (metadata?.contextUsagePercent !== void 0) {
    lines.push(`- **Context Usage**: ${metadata.contextUsagePercent}%`);
  }
  lines.push("");
  if (metadata?.filesWritten !== void 0) {
    lines.push(`- **Files Written**: ${metadata.filesWritten}`);
  }
  if (metadata?.linesAdded !== void 0) {
    lines.push(`- **Lines Added**: ${metadata.linesAdded}`);
  }
  if (metadata?.linesRemoved !== void 0) {
    lines.push(`- **Lines Removed**: ${metadata.linesRemoved}`);
  }
  if (metadata?.uniqueFiles && metadata.uniqueFiles.length > 0) {
    lines.push("");
    lines.push("<details>");
    lines.push(
      `<summary><strong>Unique Files Referenced (${metadata.uniqueFiles.length})</strong></summary>`
    );
    lines.push("");
    for (const file of metadata.uniqueFiles) {
      lines.push(`- \`${sanitizeText(file)}\``);
    }
    lines.push("</details>");
  }
  lines.push("\n---\n");
  for (const message of sessionData.messages) {
    if (message.type === "user") {
      lines.push("## User\n");
      lines.push(formatMessageContent(message));
    } else if (message.type === "assistant") {
      lines.push("## Assistant\n");
      lines.push(formatMessageContent(message));
    } else if (message.type === "tool_call") {
      lines.push(formatToolCall(message));
    } else if (message.type === "system") {
      lines.push("### System\n");
      const text = formatMessageContent(message);
      lines.push(`> ${text.replace(/\n/g, "\n> ")}`);
    }
    lines.push("\n");
  }
  return lines.join("\n");
}
__name(toMarkdown, "toMarkdown");
function formatMessageContent(message) {
  const text = extractTextFromMessage(message);
  const processedText = text.replace(
    /--- Content from referenced files ---\n([\s\S]*?)\n--- End of content ---/g,
    (match, content) => `
> **Referenced Files:**

${createCodeBlock(content)}
`
  );
  return processedText;
}
__name(formatMessageContent, "formatMessageContent");
function formatToolCall(message) {
  if (!message.toolCall) return "";
  const lines = [];
  const { title, status, rawInput, content, locations } = message.toolCall;
  const titleStr = typeof title === "string" ? title : JSON.stringify(title);
  lines.push(`### Tool: ${sanitizeText(titleStr)}`);
  lines.push(`**Status**: ${sanitizeText(status)}
`);
  if (rawInput) {
    lines.push("**Input:**");
    const inputStr = typeof rawInput === "string" ? rawInput : JSON.stringify(rawInput, null, 2);
    lines.push(createCodeBlock(inputStr, "json"));
    lines.push("");
  }
  if (locations && locations.length > 0) {
    lines.push("**Affected Files:**");
    for (const loc of locations) {
      const lineSuffix = loc.line ? `:${loc.line}` : "";
      lines.push(`- \`${sanitizeText(loc.path)}${lineSuffix}\``);
    }
    lines.push("");
  }
  if (content && content.length > 0) {
    lines.push("**Output:**");
    for (const item of content) {
      if (item.type === "content" && item["content"]) {
        const contentData = item["content"];
        if (contentData.type === "text" && contentData.text) {
          let language = "";
          if (locations && locations.length === 1 && locations[0].path) {
            language = getLanguageFromPath(locations[0].path);
          }
          lines.push(createCodeBlock(contentData.text, language));
        }
      } else if (item.type === "diff") {
        const path2 = item["path"];
        const diffText = item["newText"];
        lines.push(`
*Diff for \`${sanitizeText(path2)}\`:*`);
        lines.push(createCodeBlock(diffText, "diff"));
      }
    }
  }
  return lines.join("\n");
}
__name(formatToolCall, "formatToolCall");
function extractTextFromMessage(message) {
  if (!message.message?.parts) return "";
  const textParts = [];
  for (const part of message.message.parts) {
    if ("text" in part) {
      textParts.push(part.text);
    }
  }
  return textParts.join("\n");
}
__name(extractTextFromMessage, "extractTextFromMessage");
function createCodeBlock(content, language = "") {
  const fence = buildFence(content);
  return `${fence}${language}
${content}
${fence}`;
}
__name(createCodeBlock, "createCodeBlock");
function sanitizeText(value) {
  return (value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;");
}
__name(sanitizeText, "sanitizeText");
function buildFence(value) {
  const matches = (value ?? "").match(/`+/g);
  const maxRun = matches ? Math.max(...matches.map((match) => match.length)) : 0;
  const fenceLength = Math.max(3, maxRun + 1);
  return "`".repeat(fenceLength);
}
__name(buildFence, "buildFence");
function getLanguageFromPath(path2) {
  const ext = path2.split(".").pop()?.toLowerCase();
  switch (ext) {
    case "ts":
    case "tsx":
      return "typescript";
    case "js":
    case "jsx":
    case "mjs":
    case "cjs":
      return "javascript";
    case "py":
      return "python";
    case "rb":
      return "ruby";
    case "go":
      return "go";
    case "rs":
      return "rust";
    case "java":
      return "java";
    case "c":
    case "cpp":
    case "h":
    case "hpp":
      return "cpp";
    case "cs":
      return "csharp";
    case "html":
      return "html";
    case "css":
      return "css";
    case "json":
      return "json";
    case "md":
      return "markdown";
    case "sh":
    case "bash":
    case "zsh":
      return "bash";
    case "yaml":
    case "yml":
      return "yaml";
    case "xml":
      return "xml";
    case "sql":
      return "sql";
    default:
      return "";
  }
}
__name(getLanguageFromPath, "getLanguageFromPath");

// packages/cli/src/ui/utils/export/formatters/html.ts
init_esbuild_shims();

// packages/web-templates/src/index.ts
init_esbuild_shims();

// packages/web-templates/src/generated/insightTemplate.ts
init_esbuild_shims();
var INSIGHT_JS = '(function(e,B){"use strict";function U({data:t}){const{totalMessages:n=0,totalLinesAdded:l=0,totalLinesRemoved:s=0,totalFiles:r=0}=t,a=Object.keys(t.heatmap||{});let o=0;if(a.length>0){const c=a.map(x=>new Date(x)).map(x=>x.getTime()),d=new Date(Math.min(...c)),g=new Date(Math.max(...c)),E=Math.abs(g.getTime()-d.getTime());o=Math.ceil(E/(1e3*60*60*24))+1}const i=o>0?Math.round(n/o):0;return e.createElement("div",{className:"stats-row"},e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},n),e.createElement("div",{className:"stat-label"},"Messages")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},"+",l,"/-",s),e.createElement("div",{className:"stat-label"},"Lines")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},r),e.createElement("div",{className:"stat-label"},"Files")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},o),e.createElement("div",{className:"stat-label"},"Days")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},i),e.createElement("div",{className:"stat-label"},"Msgs/Day")))}function K({insights:t}){return e.createElement("div",{className:"grid gap-4 md:grid-cols-2 md:gap-6"},e.createElement(J,{activeHours:t.activeHours,cardClass:"glass-card p-6",sectionTitleClass:"text-lg font-semibold tracking-tight text-slate-900"}))}function J({activeHours:t,cardClass:n,sectionTitleClass:l}){const r=[{label:"Morning",time:"06:00 - 12:00",hours:[6,7,8,9,10,11],color:"#fbbf24"},{label:"Afternoon",time:"12:00 - 18:00",hours:[12,13,14,15,16,17],color:"#0ea5e9"},{label:"Evening",time:"18:00 - 22:00",hours:[18,19,20,21],color:"#6366f1"},{label:"Night",time:"22:00 - 06:00",hours:[22,23,0,1,2,3,4,5],color:"#475569"}].map(o=>{const i=o.hours.reduce((m,c)=>m+(t[c]||0),0);return{...o,total:i}}),a=Math.max(...r.map(o=>o.total));return e.createElement("div",{className:`${n} h-full flex flex-col min-h-[320px]`},e.createElement("div",{className:"flex items-center justify-between mb-4"},e.createElement("h3",{className:l},"Active Hours")),e.createElement("div",{className:"flex-1 flex flex-col justify-center gap-4"},r.map(o=>e.createElement("div",{key:o.label,className:"space-y-2"},e.createElement("div",{className:"flex justify-between items-center text-sm"},e.createElement("div",{className:"flex items-center gap-2"},e.createElement("span",{className:"rounded-full",style:{width:"12px",height:"12px",backgroundColor:o.color}}),e.createElement("span",{className:"font-medium text-slate-700"},o.label),e.createElement("span",{className:"text-xs text-slate-400 hidden xl:inline"},o.time)),e.createElement("span",{className:"font-semibold text-slate-900"},o.total)),e.createElement("div",{className:"w-full rounded-full overflow-hidden",style:{height:"12px",backgroundColor:"#e2e8f0"}},e.createElement("div",{className:"h-full rounded-full",style:{width:`${a>0?o.total/a*100:0}%`,backgroundColor:o.color}}))))))}function V({heatmap:t}){return e.createElement("div",{className:"glass-card p-6 mt-4 md:mt-6"},e.createElement("div",{className:"mb-3"},e.createElement("h3",{className:"text-lg font-semibold tracking-tight text-slate-900"},"Activity Heatmap"),e.createElement("p",{className:"text-xs text-slate-500"},"Showing past year of activity")),e.createElement("div",{className:"heatmap-container"},e.createElement("div",{className:"min-w-[720px] rounded-xl bg-white/70"},e.createElement(X,{heatmapData:t}))),e.createElement(Z,null))}function X({heatmapData:t}){const a=new Date,o=new Date(a);o.setFullYear(a.getFullYear()-1);const i=[],m=new Date(o);for(;m<=a;)i.push(new Date(m)),m.setDate(m.getDate()+1);const c=[0,2,4,10,20],d=["#ebedf0","#9be9a8","#40c463","#30a14e","#216e39"];function g(u){if(u===0)return d[0];for(let f=c.length-1;f>=1;f--)if(u>=c[f])return d[f];return d[1]}const E=50,x=20,A=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],w=o.getDay(),W=[];let h=-1,T=-100;return i.forEach((u,f)=>{const C=f+w,_=Math.floor(C/7),v=E+_*16,N=u.getMonth();N!==h&&(v-T>30&&(W.push({x:v,text:A[N]}),T=v),h=N)}),e.createElement("svg",{className:"heatmap-svg",width:1e3,height:130,viewBox:"0 0 1000 130"},i.map((u,f)=>{const C=f+w,_=Math.floor(C/7),v=u.getDay(),N=E+_*16,j=x+v*16,k=u.toISOString().split("T")[0],S=t[k]||0,L=g(S);return e.createElement("rect",{key:k,className:"heatmap-day",x:N,y:j,width:14,height:14,rx:"2",fill:L,"data-date":k,"data-count":S},e.createElement("title",null,k,": ",S," activities"))}),W.map((u,f)=>e.createElement("text",{key:f,x:u.x,y:"15",fontSize:"12",fill:"#64748b"},u.text)))}function Z(){const t=["#ebedf0","#9be9a8","#40c463","#30a14e","#216e39"];return e.createElement("div",{className:"flex items-center gap-2 mt-4"},e.createElement("span",{className:"text-xs text-slate-500"},"Less"),t.map((n,l)=>e.createElement("span",{key:l,className:"inline-block rounded",style:{width:"10px",height:"10px",backgroundColor:n}})),e.createElement("span",{className:"text-xs text-slate-500"},"More"))}function p({children:t}){if(!t||typeof t!="string")return t;const n=t.split(/(\\*\\*.*?\\*\\*)/g);return e.createElement(e.Fragment,null,n.map((l,s)=>l.startsWith("**")&&l.endsWith("**")&&l.length>=4?e.createElement("strong",{key:s},l.slice(2,-2)):l))}function F({text:t,label:n="Copy"}){const[l,s]=e.useState(!1),r=()=>{navigator.clipboard.writeText(t).then(()=>{s(!0),setTimeout(()=>s(!1),2e3)})};return e.createElement("button",{className:"copy-btn",onClick:r},l?"Copied!":n)}function R(t){return typeof t=="string"&&t.trim().length>0}function ee({qualitative:t,targetSections:n}){const{atAGlance:l}=t;if(!l)return null;const s=[{key:"wins",label:"What\'s working:",body:l.whats_working,href:"#section-wins",link:"Impressive Things You Did \u2192",showLink:n.wins},{key:"friction",label:"What\'s hindering you:",body:l.whats_hindering,href:"#section-friction",link:"Where Things Go Wrong \u2192",showLink:n.friction},{key:"features",label:"Quick wins to try:",body:l.quick_wins,href:"#section-features",link:"Features to Try \u2192",showLink:n.features},{key:"horizon",label:"Ambitious workflows:",body:l.ambitious_workflows,href:"#section-horizon",link:"On the Horizon \u2192",showLink:n.horizon}].filter(r=>R(r.body));return s.length===0?null:e.createElement("div",{className:"at-a-glance"},e.createElement("div",{className:"glance-title"},"At a Glance"),e.createElement("div",{className:"glance-sections"},s.map(r=>e.createElement("div",{key:r.key,className:"glance-section"},e.createElement("strong",null,r.label)," ",e.createElement(p,null,r.body),r.showLink&&e.createElement("a",{href:r.href,className:"see-more"},r.link)))))}function te({sections:t}){return t.length===0?null:e.createElement("nav",{className:"nav-toc"},t.map(n=>e.createElement("a",{key:n.href,href:n.href},n.label)))}function ne({qualitative:t,topGoals:n,topTools:l}){const{projectAreas:s}=t,r=Array.isArray(l)?Object.fromEntries(l):l;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-work",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"What You Work On"),Array.isArray(s==null?void 0:s.areas)&&s.areas.length>0&&e.createElement("div",{className:"project-areas mb-6"},s.areas.map((a,o)=>e.createElement("div",{key:o,className:"project-area"},e.createElement("div",{className:"area-header"},e.createElement("span",{className:"area-name"},a.name),e.createElement("span",{className:"area-count"},"~",a.session_count," sessions")),e.createElement("div",{className:"area-desc"},e.createElement(p,null,a.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(D,{data:n,title:"What You Wanted",color:"#0ea5e9"}),r&&Object.keys(r).length>0&&e.createElement(D,{data:r,title:"Top Tools Used",color:"#6366f1"})))}function le({qualitative:t,insights:n}){const{interactionStyle:l}=t;return l?e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-usage",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"How You Use Qwen Code"),e.createElement("div",{className:"narrative"},e.createElement("p",null,e.createElement(p,null,l.narrative)),l.key_pattern&&e.createElement("div",{className:"key-insight"},e.createElement("strong",null,"Key pattern:")," ",e.createElement(p,null,l.key_pattern))),e.createElement(K,{insights:n}),e.createElement(V,{heatmap:n.heatmap})):null}function re({qualitative:t,primarySuccess:n,outcomes:l}){const s=t==null?void 0:t.impressiveWorkflows;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-wins",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Impressive Things You Did"),(s==null?void 0:s.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,s.intro)),s&&e.createElement("div",{className:"big-wins"},Array.isArray(s.impressive_workflows)&&s.impressive_workflows.map((r,a)=>e.createElement("div",{key:a,className:"big-win"},e.createElement("div",{className:"big-win-title"},r.title),e.createElement("div",{className:"big-win-desc"},e.createElement(p,null,r.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginTop:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(D,{data:n,title:"What Helped Most (Qwen\'s Capabilities)",color:"#3b82f6",allowedKeys:["fast_accurate_search","correct_code_edits","good_explanations","proactive_help","multi_file_changes","good_debugging"]}),l&&Object.keys(l).length>0&&e.createElement(D,{data:l,title:"Outcomes",color:"#8b5cf6",allowedKeys:["fully_achieved","mostly_achieved","partially_achieved","not_achieved","unclear_from_transcript"]})))}function se(t){return t==="unclear_from_transcript"?"Unclear":t.split("_").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function D({data:t,title:n,color:l="#3b82f6",allowedKeys:s=null}){if(!t||Object.keys(t).length===0)return null;let r=Object.entries(t).filter(([,o])=>Number.isFinite(o)&&o!==0);if(s&&(r=r.filter(([o])=>s.includes(o))),r.sort((o,i)=>i[1]-o[1]),r=r.slice(0,10),r.length===0)return null;const a=Math.max(...r.map(([,o])=>o));return e.createElement("div",{className:"bar-chart-card",style:{flex:1,minWidth:0,backgroundColor:"#ffffff",borderRadius:"12px",padding:"20px",boxShadow:"0 1px 3px rgba(0, 0, 0, 0.08)",border:"1px solid #e2e8f0"}},e.createElement("h3",{style:{fontSize:"13px",fontWeight:700,color:"#64748b",marginTop:0,marginBottom:"16px",textTransform:"uppercase",letterSpacing:"0.5px"}},n),e.createElement("div",{className:"bar-chart",style:{display:"flex",flexDirection:"column",gap:"10px"}},r.map(([o,i])=>{const m=a>0?i/a*100:0;return e.createElement("div",{key:o,className:"bar-row",style:{display:"flex",alignItems:"center",gap:"12px"}},e.createElement("div",{className:"bar-label",style:{width:"130px",fontSize:"13px",color:"#475569",textAlign:"left",flexShrink:0,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}},se(o)),e.createElement("div",{className:"bar-wrapper",style:{flex:1,display:"flex",alignItems:"center",gap:"10px",minWidth:0}},e.createElement("div",{className:"bar-bg",style:{flex:1,height:"8px",backgroundColor:"#f1f5f9",borderRadius:"4px",overflow:"hidden"}},e.createElement("div",{className:"bar-fill",style:{width:`${m}%`,height:"100%",backgroundColor:l,borderRadius:"4px",transition:"width 0.3s ease"}})),e.createElement("span",{className:"bar-value",style:{fontSize:"13px",fontWeight:600,color:"#475569",minWidth:"24px",textAlign:"right"}},i)))})))}function ae({qualitative:t,satisfaction:n,friction:l}){const s=t==null?void 0:t.frictionPoints;return e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-friction",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Where Things Go Wrong"),(s==null?void 0:s.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,s.intro)),s&&e.createElement("div",{className:"friction-categories"},Array.isArray(s.categories)&&s.categories.map((r,a)=>e.createElement("div",{key:a,className:"friction-category"},e.createElement("div",{className:"friction-title"},r.category),e.createElement("div",{className:"friction-desc"},e.createElement(p,null,r.description)),Array.isArray(r.examples)&&r.examples.length>0&&e.createElement("ul",{className:"friction-examples"},r.examples.map((o,i)=>e.createElement("li",{key:i},e.createElement(p,null,o))))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginTop:"24px",marginBottom:"24px"}},l&&Object.keys(l).length>0&&e.createElement(D,{data:l,title:"Primary Friction Types",color:"#ef4444",allowedKeys:["misunderstood_request","wrong_approach","buggy_code","user_rejected_action","excessive_changes"]}),n&&Object.keys(n).length>0&&e.createElement(D,{data:n,title:"Inferred Satisfaction (model-estimated)",color:"#10b981",allowedKeys:["happy","satisfied","likely_satisfied","dissatisfied","frustrated"]})))}function oe({additions:t}){const[n,l]=e.useState(new Array(t.length).fill(!0)),[s,r]=e.useState(!1),a=m=>{const c=n.map((d,g)=>g===m?!d:d);l(c)},o=()=>{const m=t.filter((c,d)=>n[d]).map(c=>c.addition).join(`\n\n`);m&&navigator.clipboard.writeText(m).then(()=>{r(!0),setTimeout(()=>r(!1),2e3)})},i=n.filter(Boolean).length;return e.createElement("div",{className:"qwen-md-section"},e.createElement("h3",null,"Suggested QWEN.md Additions"),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code to add it to your QWEN.md."),e.createElement("div",{className:"qwen-md-actions",style:{marginBottom:"12px"}},e.createElement("button",{className:`copy-all-btn ${s?"copied":""}`,onClick:o,disabled:i===0},s?"Copied All!":`Copy All Checked (${i})`)),t.map((m,c)=>e.createElement("div",{key:c,className:"qwen-md-item"},e.createElement("input",{type:"checkbox",checked:n[c],onChange:()=>a(c),className:"cmd-checkbox"}),e.createElement("div",{style:{flex:1}},e.createElement("code",{className:"cmd-code"},m.addition),e.createElement("div",{className:"cmd-why"},e.createElement(p,null,m.why))),e.createElement(F,{text:m.addition}))))}function ie({qualitative:t}){const{improvements:n}=t;if(!n)return null;const l=Array.isArray(n.Qwen_md_additions)&&n.Qwen_md_additions.length>0||Array.isArray(n.features_to_try)&&n.features_to_try.length>0,s=Array.isArray(n.usage_patterns)&&n.usage_patterns.length>0;return!l&&!s?null:e.createElement(e.Fragment,null,l&&e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-features",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"Existing Qwen Code Features to Try"),Array.isArray(n.Qwen_md_additions)&&n.Qwen_md_additions.length>0&&e.createElement(oe,{additions:n.Qwen_md_additions}),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code and it\'ll set it up for you."),e.createElement("div",{className:"features-section"},Array.isArray(n.features_to_try)&&n.features_to_try.map((r,a)=>e.createElement("div",{key:a,className:"feature-card"},e.createElement("div",{className:"feature-title"},r.feature),e.createElement("div",{className:"feature-oneliner"},e.createElement(p,null,r.one_liner)),e.createElement("div",{className:"feature-why"},e.createElement("strong",null,"Why for you:")," ",e.createElement(p,null,r.why_for_you)),e.createElement("div",{className:"feature-examples"},e.createElement("div",{className:"feature-example"},e.createElement("div",{className:"example-code-row"},e.createElement("code",{className:"example-code"},r.example_code),e.createElement(F,{text:r.example_code})))))))),s&&e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-patterns",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"New Ways to Use Qwen Code"),e.createElement("p",{className:"text-xs text-slate-500 mb-3"},"Just copy this into Qwen Code and it\'ll walk you through it."),e.createElement("div",{className:"patterns-section"},Array.isArray(n.usage_patterns)&&n.usage_patterns.map((r,a)=>e.createElement("div",{key:a,className:"pattern-card"},e.createElement("div",{className:"pattern-title"},r.title),e.createElement("div",{className:"pattern-summary"},e.createElement(p,null,r.suggestion)),e.createElement("div",{className:"pattern-detail"},e.createElement(p,null,r.detail)),e.createElement("div",{className:"copyable-prompt-section"},e.createElement("div",{className:"prompt-label"},"Paste into Qwen Code:"),e.createElement("div",{className:"copyable-prompt-row"},e.createElement("code",{className:"copyable-prompt"},r.copyable_prompt),e.createElement(F,{text:r.copyable_prompt}))))))))}function me({qualitative:t}){const{futureOpportunities:n}=t;return n?e.createElement(e.Fragment,null,e.createElement("h2",{id:"section-horizon",className:"text-xl font-semibold text-slate-900 mt-8 mb-4"},"On the Horizon"),n.intro&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,n.intro)),e.createElement("div",{className:"horizon-section"},Array.isArray(n.opportunities)&&n.opportunities.map((l,s)=>e.createElement("div",{key:s,className:"horizon-card"},e.createElement("div",{className:"horizon-title"},l.title),e.createElement("div",{className:"horizon-possible"},e.createElement(p,null,l.whats_possible)),e.createElement("div",{className:"horizon-tip"},e.createElement("strong",null,"Getting started:")," ",e.createElement(p,null,l.how_to_try)),e.createElement("div",{className:"pattern-prompt"},e.createElement("div",{className:"prompt-label"},"Paste into Qwen Code:"),e.createElement("div",{style:{display:"flex",alignItems:"flex-start",gap:"8px"}},e.createElement("code",{style:{flex:1}},l.copyable_prompt),e.createElement(F,{text:l.copyable_prompt}))))))):null}function ce({qualitative:t}){const{memorableMoment:n}=t;return n?e.createElement("div",{className:"fun-ending"},e.createElement("div",{className:"fun-headline"},\'"\',n.headline,\'"\'),e.createElement("div",{className:"fun-detail"},e.createElement(p,null,n.detail))):null}const de={light:{background:"linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)",textPrimary:"#0f172a",textSecondary:"#475569",textMuted:"#64748b",cardBackground:"rgba(255,255,255,0.7)",cardBackgroundSecondary:"rgba(255,255,255,0.5)",borderColor:"#e2e8f0",heatmapColors:["#9be9a8","#40c463","#30a14e","#216e39"],heatmapEmpty:"#ebedf0"},dark:{background:"linear-gradient(135deg, #0f172a 0%, #1e293b 100%)",textPrimary:"#f8fafc",textSecondary:"#e2e8f0",textMuted:"#94a3b8",cardBackground:"rgba(255,255,255,0.05)",cardBackgroundSecondary:"rgba(255,255,255,0.04)",borderColor:"rgba(255,255,255,0.08)",heatmapColors:["#0e4429","#006d32","#26a641","#39d353"],heatmapEmpty:"#2d333b"}};function pe({data:t,theme:n="light"}){var h,T,u,f,C,_;const l=de[n],{totalMessages:s=0,totalSessions:r=0,totalLinesAdded:a=0,totalLinesRemoved:o=0,totalFiles:i=0,currentStreak:m=0,longestStreak:c=0,activeHours:d={}}=t,g=Object.keys(t.heatmap||{});let E=0,x="";if(g.length>0){E=g.length;const v=g.map(S=>new Date(S).getTime()),N=new Date(Math.min(...v)),j=new Date(Math.max(...v)),k=S=>S.toISOString().split("T")[0];x=`${k(N)} \u2014 ${k(j)}`}const A=(u=(T=(h=t.qualitative)==null?void 0:h.interactionStyle)==null?void 0:T.key_pattern)!=null?u:null,w=(_=(C=(f=t.qualitative)==null?void 0:f.memorableMoment)==null?void 0:C.headline)!=null?_:null,W=fe(t.heatmap||{},l);return e.createElement("div",{id:"share-card",style:{width:"1200px",background:l.background,color:l.textPrimary,fontFamily:\'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"\',display:"flex",flexDirection:"column",padding:"48px 56px",position:"absolute",left:"-9999px",top:"-9999px",overflow:"hidden",boxSizing:"border-box"}},e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:"32px"}},e.createElement("div",null,e.createElement("div",{style:{fontSize:"32px",fontWeight:700,letterSpacing:"-0.02em",lineHeight:1.2}},"Qwen Code Insights"),e.createElement("div",{style:{fontSize:"14px",color:l.textMuted,marginTop:"6px"}},x)),e.createElement("div",{style:{fontSize:"11px",color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.15em",paddingTop:"8px"}},"qwen.ai")),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(6, 1fr)",gap:"16px",marginBottom:"32px"}},e.createElement(M,{value:String(s),label:"Messages",theme:l}),e.createElement(M,{value:String(r),label:"Sessions",theme:l}),e.createElement(M,{value:`+${a}/-${o}`,label:"Lines Changed",small:!0,theme:l}),e.createElement(M,{value:String(i),label:"Files",theme:l}),e.createElement(M,{value:`${m}d`,label:"Streak",theme:l}),e.createElement(M,{value:`${c}d`,label:"Best Streak",theme:l})),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"24px",marginBottom:"16px"}},e.createElement("div",{style:{background:l.cardBackground,borderRadius:"12px",padding:"20px",display:"flex",flexDirection:"column"}},e.createElement("div",{style:{fontSize:"12px",fontWeight:600,color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"12px"}},"Activity \xB7 ",E," active days"),e.createElement("div",{style:{flex:1,display:"flex",alignItems:"center",justifyContent:"center"}},e.createElement(ge,{cells:W})),e.createElement(ye,{theme:l})),e.createElement("div",{style:{display:"flex",flexDirection:"column",gap:"16px"}},e.createElement("div",{style:{background:l.cardBackground,borderRadius:"12px",padding:"20px",display:"flex",flexDirection:"column"}},e.createElement("div",{style:{fontSize:"12px",fontWeight:600,color:l.textMuted,textTransform:"uppercase",letterSpacing:"0.08em",marginBottom:"12px"}},"Active Hours"),e.createElement("div",{style:{flex:1,display:"flex",flexDirection:"column",justifyContent:"center",gap:"10px"}},e.createElement(ue,{activeHours:d,theme:l}))),e.createElement("div",{style:{background:l.cardBackgroundSecondary,borderRadius:"12px",padding:"16px 16px",position:"relative"}},e.createElement("div",{style:{position:"absolute",left:"12px",fontSize:"64px",fontWeight:700,color:n==="light"?"rgba(99,102,241,0.15)":"rgba(99,102,241,0.2)",lineHeight:1,fontFamily:\'Georgia, "Times New Roman", serif\',userSelect:"none",pointerEvents:"none"}},"\u201C"),e.createElement("div",{style:{paddingLeft:"40px",position:"relative"}},A&&e.createElement("div",{style:{fontSize:"13px",color:l.textSecondary,lineHeight:1.6,marginBottom:w?"8px":0}},A),w&&e.createElement("div",{style:{fontSize:"12px",color:l.textMuted,lineHeight:1.5,fontStyle:"italic"}},w))))),e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:"auto",paddingTop:"24px",borderTop:`1px solid ${l.borderColor}`,flexShrink:0}},e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"Generated by Qwen Code \xB7 ",new Date().toISOString().split("T")[0]),e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"github.com/QwenLM/qwen-code")))}function M({value:t,label:n,small:l,theme:s}){return e.createElement("div",{style:{textAlign:"center"}},e.createElement("div",{style:{fontSize:l?"18px":"28px",fontWeight:700,color:s.textPrimary,lineHeight:1.2}},t),e.createElement("div",{style:{fontSize:"11px",color:s.textMuted,textTransform:"uppercase",letterSpacing:"0.05em",marginTop:"4px"}},n))}function ue({activeHours:t,theme:n}){const s=[{label:"Morning",time:"06\u201312",hours:[6,7,8,9,10,11],color:"#fbbf24"},{label:"Afternoon",time:"12\u201318",hours:[12,13,14,15,16,17],color:"#0ea5e9"},{label:"Evening",time:"18\u201322",hours:[18,19,20,21],color:"#6366f1"},{label:"Night",time:"22\u201306",hours:[22,23,0,1,2,3,4,5],color:"#475569"}].map(a=>({...a,total:a.hours.reduce((o,i)=>o+(t[i]||0),0)})),r=Math.max(...s.map(a=>a.total),1);return e.createElement(e.Fragment,null,s.map(a=>{const o=r>0?a.total/r*100:0;return e.createElement("div",{key:a.label},e.createElement("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",fontSize:"12px",marginBottom:"4px"}},e.createElement("div",{style:{display:"flex",alignItems:"center",gap:"6px"}},e.createElement("span",{style:{width:"8px",height:"8px",borderRadius:"50%",backgroundColor:a.color,display:"inline-block",flexShrink:0}}),e.createElement("span",{style:{color:n.textSecondary,fontWeight:500}},a.label),e.createElement("span",{style:{color:n.textMuted,fontSize:"11px"}},a.time)),e.createElement("span",{style:{color:n.textMuted,fontWeight:600}},a.total)),e.createElement("div",{style:{height:"6px",background:n.borderColor,borderRadius:"3px",overflow:"hidden"}},e.createElement("div",{style:{width:`${o}%`,height:"100%",backgroundColor:a.color,borderRadius:"3px"}})))}))}function fe(t,n){const l=new Date,r=26*7,a=new Date(l);a.setDate(a.getDate()-r+1),a.setDate(a.getDate()-a.getDay());const o=[],i=new Date(l);i.setDate(i.getDate()+(6-i.getDay()));const m=new Date(a);for(;m<=i;){const c=m.toISOString().split("T")[0],d=t[c]||0;o.push({color:he(d,n)}),m.setDate(m.getDate()+1)}return o}function he(t,n){return t===0?n.heatmapEmpty:t<2?n.heatmapColors[0]:t<4?n.heatmapColors[1]:t<10?n.heatmapColors[2]:n.heatmapColors[3]}function ge({cells:t}){const l=Math.ceil(t.length/7),s=14,r=3,a=l*(s+r),o=7*(s+r);return e.createElement("svg",{width:a,height:o,viewBox:`0 0 ${a} ${o}`},t.map((i,m)=>{const c=Math.floor(m/7),d=m%7;return e.createElement("rect",{key:m,x:c*(s+r),y:d*(s+r),width:s,height:s,rx:2,fill:i.color})}))}function ye({theme:t}){return e.createElement("div",{style:{display:"flex",alignItems:"center",gap:"8px",marginTop:"12px"}},e.createElement("span",{style:{fontSize:"11px",color:t.textMuted}},"Less"),[t.heatmapEmpty,t.heatmapColors[0],t.heatmapColors[1],t.heatmapColors[2],t.heatmapColors[3]].map((n,l)=>e.createElement("span",{key:l,style:{width:"10px",height:"10px",borderRadius:"2px",backgroundColor:n,display:"inline-block"}})),e.createElement("span",{style:{fontSize:"11px",color:t.textMuted}},"More"))}function b(t){return typeof t=="string"?t.trim().length>0:typeof t=="number"?Number.isFinite(t)&&t!==0:typeof t=="boolean"?t:Array.isArray(t)?t.some(n=>b(n)):t&&typeof t=="object"?Object.values(t).some(n=>b(n)):!1}function z(t){return Array.isArray(t)?t.some(([,n])=>Number.isFinite(n)&&n!==0):!!t&&Object.values(t).some(n=>Number.isFinite(n)&&n!==0)}function H(t){return Array.isArray(t)&&t.some(n=>b(n))}function xe({data:t}){var u,f,C,_,v,N,j,k,S,L,G,Y;const[n,l]=e.useState("dark"),s=e.useRef(!1),r=async()=>{const q=document.getElementById("share-card");if(!q||!window.html2canvas){alert("Export functionality is not available.");return}try{const y=q.cloneNode(!0);y.style.position="fixed",y.style.left="-9999px",y.style.top="0",y.style.pointerEvents="none",document.body.appendChild(y);const Q=await window.html2canvas(y,{scale:2,useCORS:!0,logging:!1,width:1200,height:y.scrollHeight});document.body.removeChild(y);const P=Q.toDataURL("image/png"),I=document.createElement("a");I.href=P,I.download=`qwen-insights-card-${new Date().toISOString().slice(0,10)}.png`,I.click()}catch(y){console.error("Export card error:",y),alert("Failed to export card. Please try again.")}};e.useEffect(()=>{s.current&&(s.current=!1,r())},[n]);const a=q=>{q===n?r():(s.current=!0,l(q))};if(!t)return e.createElement("div",{className:"text-center text-slate-600"},"No insight data available");const o=Object.keys(t.heatmap||{});let i="";if(o.length>0){const y=o.map(O=>new Date(O)).map(O=>O.getTime()),Q=new Date(Math.min(...y)),P=new Date(Math.max(...y)),I=O=>O.toISOString().split("T")[0];i=`${I(Q)} to ${I(P)}`}const m=b((u=t.qualitative)==null?void 0:u.atAGlance),c=!!t.qualitative&&(b(t.qualitative.projectAreas)||z(t.topGoals)||z(t.topTools)),d=b((f=t.qualitative)==null?void 0:f.interactionStyle),g=!!t.qualitative&&(b(t.qualitative.impressiveWorkflows)||z(t.primarySuccess)||z(t.outcomes)),E=!!t.qualitative&&(b(t.qualitative.frictionPoints)||z(t.satisfaction)||z(t.friction)),x=!!t.qualitative&&(H((C=t.qualitative.improvements)==null?void 0:C.Qwen_md_additions)||H((_=t.qualitative.improvements)==null?void 0:_.features_to_try)),A=!!t.qualitative&&H((v=t.qualitative.improvements)==null?void 0:v.usage_patterns),w=b((N=t.qualitative)==null?void 0:N.futureOpportunities),W=b((j=t.qualitative)==null?void 0:j.memorableMoment),h=[];c&&h.push({href:"#section-work",label:"What You Work On"}),d&&h.push({href:"#section-usage",label:"How You Use Qwen Code"}),g&&h.push({href:"#section-wins",label:"Impressive Things"}),E&&h.push({href:"#section-friction",label:"Where Things Go Wrong"}),x&&h.push({href:"#section-features",label:"Features to Try"}),A&&h.push({href:"#section-patterns",label:"New Usage Patterns"}),w&&h.push({href:"#section-horizon",label:"On the Horizon"});const T={wins:g,friction:E,features:x,horizon:w};return e.createElement("div",null,e.createElement("header",{className:"insights-header"},e.createElement("div",{className:"header-content"},e.createElement("div",{className:"header-title-section"},e.createElement("h1",{className:"header-title"},"Qwen Code Insights"),e.createElement("p",{className:"header-subtitle"},t.totalMessages?`${t.totalMessages.toLocaleString()} messages across ${(k=t.totalSessions)==null?void 0:k.toLocaleString()} sessions`:"Your personalized coding journey and patterns",i&&` \xB7 ${i}`)),e.createElement(Ee,{onExport:a}))),m&&t.qualitative&&e.createElement(ee,{qualitative:t.qualitative,targetSections:T}),h.length>0&&e.createElement(te,{sections:h}),e.createElement(U,{data:t}),c&&t.qualitative&&e.createElement(ne,{qualitative:t.qualitative,topGoals:t.topGoals,topTools:t.topTools}),d&&t.qualitative&&e.createElement(le,{qualitative:t.qualitative,insights:t}),g&&e.createElement(re,{qualitative:t.qualitative,primarySuccess:(S=t.primarySuccess)!=null?S:{},outcomes:(L=t.outcomes)!=null?L:{}}),E&&e.createElement(ae,{qualitative:t.qualitative,satisfaction:(G=t.satisfaction)!=null?G:{},friction:(Y=t.friction)!=null?Y:{}}),(x||A)&&t.qualitative&&e.createElement(ie,{qualitative:t.qualitative}),w&&t.qualitative&&e.createElement(me,{qualitative:t.qualitative}),W&&t.qualitative&&e.createElement(ce,{qualitative:t.qualitative}),e.createElement(pe,{data:t,theme:n}))}function Ee({onExport:t}){const[n,l]=e.useState(!1),s=e.useRef(null);e.useEffect(()=>{if(!n)return;const a=o=>{s.current&&!s.current.contains(o.target)&&l(!1)};return document.addEventListener("mousedown",a),()=>document.removeEventListener("mousedown",a)},[n]);const r=a=>{l(!1),t(a)};return e.createElement("div",{className:"export-dropdown-wrapper",ref:s},e.createElement("button",{className:"export-card-btn",onClick:()=>l(!n)},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("path",{d:"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"}),e.createElement("polyline",{points:"16 6 12 2 8 6"}),e.createElement("line",{x1:"12",y1:"2",x2:"12",y2:"15"})),e.createElement("span",null,"Export Card"),e.createElement("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:`export-chevron ${n?"open":""}`},e.createElement("polyline",{points:"6 9 12 15 18 9"}))),n&&e.createElement("div",{className:"export-dropdown"},e.createElement("button",{className:"export-dropdown-item",onClick:()=>r("light")},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("circle",{cx:"12",cy:"12",r:"5"}),e.createElement("line",{x1:"12",y1:"1",x2:"12",y2:"3"}),e.createElement("line",{x1:"12",y1:"21",x2:"12",y2:"23"}),e.createElement("line",{x1:"4.22",y1:"4.22",x2:"5.64",y2:"5.64"}),e.createElement("line",{x1:"18.36",y1:"18.36",x2:"19.78",y2:"19.78"}),e.createElement("line",{x1:"1",y1:"12",x2:"3",y2:"12"}),e.createElement("line",{x1:"21",y1:"12",x2:"23",y2:"12"}),e.createElement("line",{x1:"4.22",y1:"19.78",x2:"5.64",y2:"18.36"}),e.createElement("line",{x1:"18.36",y1:"5.64",x2:"19.78",y2:"4.22"})),e.createElement("span",null,"Light Theme")),e.createElement("button",{className:"export-dropdown-item",onClick:()=>r("dark")},e.createElement("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},e.createElement("path",{d:"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"})),e.createElement("span",null,"Dark Theme"))))}const $=document.getElementById("react-root");$&&window.INSIGHT_DATA&&B?B.createRoot($).render(e.createElement(xe,{data:window.INSIGHT_DATA})):console.error("Failed to mount React app:",{container:!!$,data:!!window.INSIGHT_DATA,ReactDOM:!!B})})(React,ReactDOM);';
var INSIGHT_CSS = '*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: #3b82f680;--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content: ""}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}body{line-height:inherit;margin:0;background-image:linear-gradient(to bottom right,var(--tw-gradient-stops));--tw-gradient-from: #f8fafc var(--tw-gradient-from-position);--tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #fff var(--tw-gradient-via-position), var(--tw-gradient-to);--tw-text-opacity: 1;min-height:100vh;color:rgb(15 23 42 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glass-card{--tw-border-opacity: 1;border-width:1px;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1));--tw-shadow: 0 10px 40px #0f172a14;--tw-shadow-colored: 0 10px 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);--tw-backdrop-blur: blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);background-color:#fff9;border-radius:1rem}.col-span-2{grid-column:span 2 / span 2}.mx-auto{margin-left:auto;margin-right:auto}.mb-8{margin-bottom:2rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-56{height:14rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-full{width:100%}.min-w-\\[720px\\]{min-width:720px}.max-w-6xl{max-width:72rem}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-slate-200>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(226 232 240 / var(--tw-divide-opacity, 1))}.overflow-x-auto{overflow-x:auto}.rounded-full{border-radius:9999px}.rounded-xl{border-radius:1.25rem}.border{border-width:1px}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.bg-emerald-50{--tw-bg-opacity: 1;background-color:rgb(236 253 245 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-slate-50{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-white\\/70{background-color:#ffffff73}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-slate-50{--tw-gradient-from: #f8fafc var(--tw-gradient-from-position);--tw-gradient-to: #f8fafc00 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-white{--tw-gradient-to: #ffffff00 var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #ffffff var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-slate-100{--tw-gradient-to: #f1f5f9 var(--tw-gradient-to-position)}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tracking-\\[0\\.2em\\]{letter-spacing:.2em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-rose-700{--tw-text-opacity: 1;color:rgb(190 18 60 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 #0000000d;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 10px 40px #0f172a14;--tw-shadow-colored: 0 10px 40px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-slate-100{--tw-shadow-color: #f1f5f9;--tw-shadow: var(--tw-shadow-colored)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\\:-translate-y-\\[1px\\]:hover{--tw-translate-y: -1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus-visible\\:outline:focus-visible{outline-style:solid}.focus-visible\\:outline-2:focus-visible{outline-width:2px}.focus-visible\\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\\:outline-slate-400:focus-visible{outline-color:#94a3b8}.active\\:translate-y-\\[1px\\]:active{--tw-translate-y: 1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\\:translate-x-0\\.5{--tw-translate-x: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@media (min-width: 768px){.md\\:mt-6{margin-top:1.5rem}.md\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\\:gap-6{gap:1.5rem}.md\\:py-12{padding-top:3rem;padding-bottom:3rem}.md\\:text-4xl{font-size:2.25rem;line-height:2.5rem}}.heatmap-container{width:100%;overflow-x:auto}.heatmap-svg{min-width:720px}.heatmap-day{cursor:pointer}.heatmap-day:hover{stroke:#00000024;stroke-width:1px}.heatmap-legend{display:flex;align-items:center;gap:4px;font-size:12px;color:#64748b;margin-top:8px}.heatmap-legend-item{width:10px;height:10px;border-radius:2px}.nav-toc{display:flex;flex-wrap:wrap;gap:8px;margin:24px 0 32px;padding:16px;background:#fff;border-radius:8px;border:1px solid #e2e8f0}.nav-toc a{font-size:12px;color:#64748b;text-decoration:none;padding:6px 12px;border-radius:6px;background:#f1f5f9;transition:all .15s}.nav-toc a:hover{background:#e2e8f0;color:#334155}.at-a-glance{background:linear-gradient(135deg,#fef3c7,#fde68a);border:1px solid #f59e0b;border-radius:12px;padding:20px 24px;margin-bottom:32px}.glance-title{font-size:16px;font-weight:700;color:#92400e;margin-bottom:16px}.glance-sections{display:flex;flex-direction:column;gap:12px}.glance-section{font-size:14px;color:#78350f;line-height:1.6}.glance-section strong{color:#92400e;font-weight:700}.see-more{color:#b45309;text-decoration:none;font-size:13px;white-space:nowrap;margin-left:4px}.see-more:hover{text-decoration:underline}.project-areas{display:flex;flex-direction:column;gap:12px;margin-bottom:32px}.project-area{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:16px}.area-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.area-name{font-weight:600;font-size:15px;color:#0f172a}.area-count{font-size:12px;color:#64748b;background:#f1f5f9;padding:2px 8px;border-radius:4px}.area-desc{font-size:14px;color:#475569;line-height:1.5}.narrative{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:20px;margin-bottom:24px}.narrative p{margin-top:0;margin-bottom:12px;font-size:14px;color:#475569;line-height:1.7}.key-insight{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:12px 16px;margin-top:12px;font-size:14px;color:#166534}.section-intro{font-size:14px;color:#64748b;margin-bottom:16px}.big-wins{display:flex;flex-direction:column;gap:12px;margin-bottom:24px}.big-win{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:8px;padding:16px}.big-win-title{font-weight:600;font-size:15px;color:#166534;margin-bottom:8px}.big-win-desc{font-size:14px;color:#15803d;line-height:1.5}.friction-categories{display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.friction-category{background:#fef2f2;border:1px solid #fca5a5;border-radius:8px;padding:16px}.friction-title{font-weight:600;font-size:15px;color:#991b1b;margin-bottom:6px}.friction-desc{font-size:13px;color:#7f1d1d;margin-bottom:10px}.friction-examples{margin:0 0 0 10px;padding:0;font-size:13px;color:#334155;list-style-type:disc}.friction-examples li{margin-bottom:4px}.qwen-md-section{background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px;margin-bottom:20px}.qwen-md-section h3{font-size:13px;font-weight:600;color:#1e40af;margin:0 0 8px}.qwen-md-actions{margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid #dbeafe}.copy-all-btn{background:#2563eb;color:#fff;border:none;border-radius:4px;padding:4px 10px;font-size:11px;cursor:pointer;font-weight:500;transition:all .2s}.copy-all-btn:hover{background:#1d4ed8}.copy-all-btn.copied{background:#16a34a}.qwen-md-item{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;padding:8px 0;border-bottom:1px solid #dbeafe}.qwen-md-item:last-child{border-bottom:none}.cmd-checkbox{margin-top:2px}.cmd-code{background:#fff;padding:6px 10px;border-radius:4px;font-size:11px;color:#1e40af;border:1px solid #bfdbfe;font-family:monospace;display:block;white-space:pre-wrap;word-break:break-word;flex:1}.cmd-why{font-size:11px;color:#64748b;width:100%;padding-left:20px;margin-top:4px}.features-section,.patterns-section{display:flex;flex-direction:column;gap:12px;margin:16px 0}.feature-card{background:#f0fdf4;border:1px solid #86efac;border-radius:8px;padding:16px}.pattern-card{background:#f0f9ff;border:1px solid #7dd3fc;border-radius:8px;padding:16px}.feature-title,.pattern-title{font-weight:600;font-size:15px;color:#0f172a;margin-bottom:6px}.feature-oneliner,.pattern-summary{font-size:14px;color:#475569;margin-bottom:8px}.feature-why,.pattern-detail{font-size:13px;color:#334155;line-height:1.5}.feature-examples{margin-top:12px}.feature-example{padding:8px 0;border-top:1px solid #d1fae5}.feature-example:first-child{border-top:none}.example-code-row,.copyable-prompt-row{display:flex;align-items:flex-start;gap:8px}.example-code{flex:1;background:#f1f5f9;padding:8px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155;overflow-x:auto;white-space:pre-wrap}.copyable-prompt-section{margin-top:12px;padding-top:12px;border-top:1px solid #e2e8f0}.copyable-prompt{flex:1;background:#f8fafc;padding:10px 12px;border-radius:4px;font-family:monospace;font-size:12px;color:#334155;border:1px solid #e2e8f0;white-space:pre-wrap;line-height:1.5}.prompt-label{font-size:11px;font-weight:600;text-transform:uppercase;color:#64748b;margin-bottom:6px}.copy-btn{background:#e2e8f0;border:none;border-radius:4px;padding:4px 8px;font-size:11px;cursor:pointer;color:#475569;flex-shrink:0;transition:all .2s}.copy-btn:hover{background:#cbd5e1}.horizon-section{display:flex;flex-direction:column;gap:16px}.horizon-card{background:linear-gradient(135deg,#faf5ff,#f5f3ff);border:1px solid #c4b5fd;border-radius:8px;padding:16px}.horizon-title{font-weight:600;font-size:15px;color:#5b21b6;margin-bottom:8px}.horizon-possible{font-size:14px;color:#334155;margin-bottom:10px;line-height:1.5}.horizon-tip{font-size:13px;color:#6b21a8;background:#fff9;padding:8px 12px;border-radius:4px}.pattern-prompt{background:#f8fafc;padding:12px;border-radius:6px;margin-top:12px;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:8px}.pattern-prompt code{font-family:monospace;font-size:12px;color:#334155;display:block;white-space:pre-wrap}.fun-ending{background:linear-gradient(135deg,#fef3c7,#fde68a);border:1px solid #fbbf24;border-radius:12px;padding:24px;margin-top:40px;text-align:center}.fun-headline{font-size:18px;font-weight:600;color:#78350f;margin-bottom:8px}.fun-detail{font-size:14px;color:#92400e}.stats-row{display:flex;gap:24px;margin-bottom:40px;padding:20px 0;border-top:1px solid #e2e8f0;border-bottom:1px solid #e2e8f0;flex-wrap:wrap}.stat{text-align:center}.stat-value{font-size:24px;font-weight:700;color:#0f172a}.stat-label{font-size:11px;color:#64748b;text-transform:uppercase}@media (max-width: 640px){.stats-row{justify-content:center}}.header-with-action{position:relative}.insights-header{margin-bottom:2rem;padding:1.5rem 0;border-bottom:1px solid #e2e8f0}.header-content{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap}.header-title-section{flex:1;min-width:0}.header-title{font-size:1.75rem;font-weight:700;color:#0f172a;letter-spacing:-.02em;margin:0 0 .375rem;line-height:1.2}.header-subtitle{font-size:.875rem;color:#64748b;margin:0;font-weight:400}.export-dropdown-wrapper{position:relative}.export-card-btn{display:inline-flex;align-items:center;gap:.5rem;height:36px;padding:0 .875rem;border:1px solid #e2e8f0;border-radius:8px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500;cursor:pointer;transition:all .15s ease}.export-card-btn:hover{background:#f8fafc;border-color:#cbd5e1}.export-card-btn:active{background:#f1f5f9}.export-chevron{transition:transform .15s ease;opacity:.5}.export-chevron.open{transform:rotate(180deg)}.export-dropdown{position:absolute;top:calc(100% + 4px);right:0;min-width:160px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 16px #00000014;padding:4px;z-index:50}.export-dropdown-item{display:flex;align-items:center;gap:.5rem;width:100%;padding:.5rem .75rem;border:none;border-radius:6px;background:none;color:#334155;font-size:.8125rem;font-weight:400;cursor:pointer;transition:background .1s ease}.export-dropdown-item:hover{background:#f1f5f9}.export-dropdown-item:active{background:#e2e8f0}@media (max-width: 640px){.header-content{flex-direction:column;align-items:flex-start;gap:1rem}.header-title{font-size:1.5rem}}';

// packages/web-templates/src/generated/exportHtmlTemplate.ts
init_esbuild_shims();
var HTML_TEMPLATE = '<!doctype html>\n<html lang="en" class="dark">\n  <head>\n    <meta charset="UTF-8" />\n    <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n    <link\n      rel="icon"\n      type="image/svg+xml"\n      href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20141.38%20140%22%3E%0A%20%20%3Cpath%0A%20%20%20%20fill%3D%22%23000000%22%0A%20%20%20%20d%3D%22m140.93%2085-16.35-28.33-1.93-3.34%208.66-15a3.323%203.323%200%200%200%200-3.34l-9.62-16.67c-.3-.51-.72-.93-1.22-1.22s-1.07-.45-1.67-.45H82.23l-8.66-15a3.33%203.33%200%200%200-2.89-1.67H51.43c-.59%200-1.17.16-1.66.45-.5.29-.92.71-1.22%201.22L32.19%2029.98l-1.92%203.33H12.96c-.59%200-1.17.16-1.66.45-.5.29-.93.71-1.22%201.22L.45%2051.66a3.323%203.323%200%200%200%200%203.34l18.28%2031.67-8.66%2015a3.32%203.32%200%200%200%200%203.34l9.62%2016.67c.3.51.72.93%201.22%201.22s1.07.45%201.67.45h36.56l8.66%2015a3.35%203.35%200%200%200%202.89%201.67h19.25a3.34%203.34%200%200%200%202.89-1.67l18.28-31.67h17.32c.6%200%201.17-.16%201.67-.45s.92-.71%201.22-1.22l9.62-16.67a3.323%203.323%200%200%200%200-3.34ZM51.44%203.33%2061.07%2020l-9.63%2016.66h76.98l-9.62%2016.66H45.67l-11.54-20zM57.21%20120H22.58l9.63-16.67h19.25l-38.5-66.67h19.25l9.62%2016.67L68.78%20100l-11.55%2020Zm61.59-33.34-9.62-16.67-38.49%2066.67-9.63-16.67%209.63-16.66%2026.94-46.67h23.1l17.32%2030z%22%0A%20%20%2F%3E%0A%3C%2Fsvg%3E"\n    />\n    <script\n      crossorigin\n      src="https://unpkg.com/react@18.2.0/umd/react.production.min.js"\n    ></script>\n    <script\n      crossorigin\n      src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js"\n    ></script>\n    <script>\n      const withKey = (props, key) =>\n        key == null ? props : Object.assign({}, props, { key });\n      const jsx = (type, props, key) =>\n        React.createElement(type, withKey(props, key));\n      const jsxRuntime = {\n        Fragment: React.Fragment,\n        jsx,\n        jsxs: jsx,\n        jsxDEV: jsx,\n      };\n      window.ReactJSXRuntime = jsxRuntime;\n      window[\'react/jsx-runtime\'] = jsxRuntime;\n      window[\'react/jsx-dev-runtime\'] = jsxRuntime;\n    </script>\n    <script src="https://unpkg.com/@qwen-code/webui@latest/dist/index.umd.js"></script>\n    <link\n      rel="stylesheet"\n      href="https://unpkg.com/@qwen-code/webui@latest/dist/styles.css"\n    />\n    <title>Qwen Code Chat Export</title>\n    <script>\n      // Pre-hydrate FOUC guard: must run before <style> below applies layout.\n      // The storage key \'qwen-export-theme\' is duplicated here verbatim and\n      // MUST stay in sync with EXPORT_THEME_STORAGE_KEY in\n      // src/components/useExportTheme.ts.\n      (function () {\n        try {\n          var stored = window.localStorage.getItem(\'qwen-export-theme\');\n          var theme = stored === \'light\' || stored === \'dark\' ? stored : \'dark\';\n          var root = document.documentElement;\n          // Toggle-style writes mirror the React hook\'s effect, so the two\n          // code paths converge on identical class state.\n          root.classList.toggle(\'light\', theme === \'light\');\n          root.classList.toggle(\'dark\', theme === \'dark\');\n        } catch (e) {\n          // localStorage may be unavailable (private mode, file:// sandbox);\n          // the static class="dark" attribute on <html> remains the default.\n        }\n      })();\n    </script>\n    <style>\n      @font-face {\n        font-family: "Press Start 2P";\n        font-style: normal;\n        font-weight: 400;\n        font-display: swap;\n        src: url("data:font/woff2;base64,d09GMgABAAAAAALQAAwAAAAABfwAAAKBAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCgGYABUEQgKgkSCDAsOAAE2AiQDDgQgBYRKByAb4QTIBB76Oev9JKW02x5ClpELSxHm1M0JQ+OBJAtDpAAVUQ7i///V+A/YgLVswlGo/7a+lmW3sfnUvoBFcUKzUFEnKo08S0F2T8TiAAJQieDvSGUVdW3smBv2LuCGjSpG3jQTD/m9OI5lTDomdQG1hkoMkCJu1ZYsmL42dEu7W8q5gUan/J6yyO+FX5NO5qQPxaqGnEINZ2q7kDf0+i4UigAXdiQUNMppoJnOzcxnDMwX5lXzinnJPDtkzhQFwjTx0DGrx1zkoNhIYr5LTKHjclcs+z3Frrh2ue3Kvk6bxzoRJLsIQpWcQhW27bgJwoUHYXNi2WWnVRUWaVNS0XMJ1eIUHlSX0l3l7BZOOos1ySk7NUWl6+eobG3Nfpj96g8EvukB3Qjouo4+O6svG9/0b8ZyKmfoZj9gzBqq8I2MS7Pf2JquL9vZwHJ51djyD01vbVHRDxSslvFBZwMHjQvexMxIvz3oyftul2+k9yBS+xGM+l+d+Pvo/zH5fVXMRvsHhG4u9/dRsgQyF67l9+jYgZuy+Ath2O6EUzU7E6BxF41nQk2cgkN8IIlOPKecMgWccSrE4XdaOECf00oUaeTm34EpvHhZIodEEllllBWmWcJLyQmsPjNHAousMEkijVRQR5OgNc4qq7TiZZg89pJCE/G0MM4kPuYqqIOKrQw3WmQBjVQSSLLm1H1NiGmCN21uwK/JpZRuWignd/klmbWXFEtZZIn1o8cmkaDqX5JIJgWNNqYYR9s0GsRFZhhntKJSjI+KTaFDZ+MoRllkjHWK2ADCxilLQGTkJZo4NAJMDwhAiK0CJD+jjKFRwWBapYFh5rdzfogQC/m1XLplXiEFEwAA") format("woff2");\n      }\n      :root{--bg-primary: #18181b;--bg-secondary: #27272a;--text-primary: #f4f4f5;--text-secondary: #a1a1aa;--border-color: #3f3f46;--accent-color: #3b82f6;--header-bg: rgba(24, 24, 27, .95);--scrollbar-thumb-hover: #52525b}:root.light{--bg-primary: #ffffff;--bg-secondary: #f3f4f6;--text-primary: #1f2937;--text-secondary: #6b7280;--border-color: #e5e7eb;--accent-color: #2563eb;--header-bg: rgba(249, 250, 251, .95);--scrollbar-thumb-hover: #d1d5db;--app-primary-foreground: #1f2937;--app-secondary-foreground: #6b7280;--app-background: #ffffff;--app-primary-background: #ffffff;--app-background-secondary: #f3f4f6;--app-background-tertiary: #e5e7eb;--app-foreground: #1f2937;--app-foreground-secondary: #6b7280;--app-foreground-muted: #9ca3af;--app-border: #e5e7eb;--app-primary-border-color: #e5e7eb;--app-input-background: #ffffff;--app-input-border: #d1d5db;--app-input-placeholder-foreground: #9ca3af;--app-ghost-button-hover-background: rgba(0, 0, 0, .05);--app-header-background: #f9fafb;--app-list-hover-background: rgba(0, 0, 0, .05);--app-list-active-background: #3b82f6;--app-menu-background: #ffffff;--app-menu-border: #e5e7eb;--app-menu-foreground: #1f2937;--app-tool-background: #ffffff;--app-code-background: #f3f4f6;--app-secondary-background: #f3f4f6;--app-input-secondary-background: #f3f4f6;--app-input-foreground: #1f2937;--app-button-background: #e5e7eb;--app-button-secondary-background: #f3f4f6;--app-button-foreground: #1f2937;--app-transparent-inner-border: rgba(0, 0, 0, .1);--app-warning-foreground: #b45309}body{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;margin:0;padding:0;background-color:var(--bg-primary);color:var(--text-primary);line-height:1.6;-webkit-font-smoothing:antialiased}.page-wrapper{min-height:100vh;display:flex;flex-direction:column;align-items:center}.header{width:100%;padding:16px 24px;border-bottom:1px solid var(--border-color);background-color:var(--header-bg);backdrop-filter:blur(8px);position:sticky;top:0;z-index:100;display:flex;justify-content:space-between;align-items:center;box-sizing:border-box}.header-left{display:flex;align-items:center;gap:12px}.header-right{display:flex;align-items:center;gap:8px}.theme-toggle{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;background:transparent;border:1px solid var(--border-color);border-radius:999px;color:var(--text-secondary);cursor:pointer;transition:background-color .15s ease,color .15s ease,border-color .15s ease}.theme-toggle:hover{background-color:var(--bg-secondary);color:var(--text-primary)}.theme-toggle:focus-visible{outline:2px solid var(--accent-color);outline-offset:2px}.theme-toggle:active{transform:scale(.95)}.logo-icon{width:24px;height:24px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.logo-icon svg{width:100%;height:100%}.logo{display:flex;flex-direction:column;line-height:1}.logo-text{font-family:"Press Start 2P",cursive;font-weight:400;font-size:24px;letter-spacing:-.05em;position:relative;color:#fff}.logo-text-inner{background:linear-gradient(to right,#60a5fa,#a855f7);-webkit-background-clip:text;-webkit-text-fill-color:transparent;position:relative;z-index:2}.logo-text:before,.logo-text:after{content:attr(data-text);position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;background:none;-webkit-text-fill-color:transparent;-webkit-text-stroke:1px rgba(96,165,250,.3)}.logo-text:before{transform:translate(2px,2px);-webkit-text-stroke:1px rgba(168,85,247,.3)}.logo-text:after{transform:translate(4px,4px);opacity:.4}.logo-sub{font-size:11px;font-weight:600;color:var(--text-secondary);letter-spacing:.05em;text-transform:uppercase;margin-top:4px}.badge{font-size:11px;padding:2px 8px;border-radius:999px;background-color:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--border-color);font-weight:500}.meta{display:flex;gap:24px;font-size:13px;color:var(--text-secondary)}.meta-item{display:flex;align-items:center;gap:8px}.meta-label{color:var(--text-secondary)}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:var(--bg-primary)}::-webkit-scrollbar-thumb{background:var(--bg-secondary);border-radius:5px;border:2px solid var(--bg-primary)}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-thumb-hover)}@media (max-width: 768px){.chat-container{max-width:100%;padding:20px 16px}.header{padding:12px 16px}.meta{width:100%;flex-direction:column;gap:6px}}@media (max-width: 480px){.chat-container{padding:16px 12px}}.content-wrapper{display:flex;width:100%;max-width:1600px;height:calc(100vh - 73px)}.chat-container{flex:1;min-width:0;overflow-y:auto;padding:24px;box-sizing:border-box}.metadata-sidebar{width:320px;min-width:320px;padding:12px;border-right:1px solid var(--border-color);background-color:var(--bg-secondary);display:flex;flex-direction:column;gap:12px;overflow-y:auto;height:100%;box-sizing:border-box}.metadata-section{display:flex;flex-direction:column;gap:8px}.metadata-section-title{font-size:10px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.05em;margin:0;padding-bottom:4px;border-bottom:1px solid var(--border-color)}.metadata-section-small{margin-top:auto;padding-top:12px;border-top:1px solid var(--border-color)}.metadata-item{display:flex;flex-direction:column;gap:2px}.metadata-item-empty{font-size:12px;color:var(--text-secondary);margin:0;padding:4px 0}.metadata-content{display:flex;flex-direction:column;gap:2px;min-width:0}.metadata-content .metadata-label{font-size:10px;color:var(--text-secondary)}.metadata-content .metadata-value{font-size:12px;color:var(--text-primary);word-break:break-all;line-height:1.3;cursor:pointer}.metadata-content .metadata-value.multiline{white-space:pre-wrap}.metadata-content .metadata-value.text-green{color:#22c55e}.metadata-content .metadata-value.text-red{color:#ef4444}.metadata-value-with-copy{display:flex;align-items:center;gap:8px}.metadata-value-with-copy .metadata-value{flex:1;min-width:0}.copy-button{display:inline-flex;align-items:center;justify-content:center;padding:4px;background:transparent;border:1px solid var(--border-color, #3f3f46);border-radius:4px;color:var(--text-secondary, #a1a1aa);cursor:pointer;transition:all .15s ease;flex-shrink:0}.copy-button:hover{background:var(--bg-hover, #27272a);color:var(--text-primary, #f4f4f5);border-color:var(--border-hover, #52525b)}.copy-button:active{transform:scale(.95)}@media (max-width: 1024px){.metadata-sidebar{width:320px;min-width:320px;padding:10px}}@media (max-width: 768px){.content-wrapper{flex-direction:column;height:auto}.chat-container{height:auto;min-height:50vh}.metadata-sidebar{width:100%;min-width:100%;height:auto;max-height:none;border-right:none;border-top:1px solid var(--border-color);padding:12px;gap:12px}.metadata-section{flex-direction:row;flex-wrap:wrap;gap:12px}.metadata-section-title{width:100%;border-bottom:none;padding-bottom:0}.metadata-item{flex:1;min-width:140px}.metadata-section-small{margin-top:0;padding-top:0;border-top:none}}.modal-overlay{position:fixed;inset:0;z-index:1000;background-color:#0009;display:flex;align-items:center;justify-content:center;padding:24px}.modal-container{background-color:var(--bg-secondary);border:1px solid var(--border-color);border-radius:12px;width:100%;max-width:800px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 25px 50px -12px #00000080}.modal-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border-color);flex-shrink:0}.modal-title{font-size:13px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.modal-close{background:none;border:none;color:var(--text-secondary);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:6px;line-height:1;transition:background-color .15s,color .15s}.modal-close:hover{background-color:var(--border-color);color:var(--text-primary)}.modal-content{margin:0;padding:16px;overflow:auto;font-size:13px;line-height:1.6;color:var(--text-primary);white-space:pre-wrap;word-break:break-word}\n    </style>\n  </head>\n  <body>\n    <div id="app"></div>\n\n    <script id="chat-data" type="application/json"></script>\n    <script>\n      (()=>{var f=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 141.38 140">\n  <path\n    fill="#000000"\n    d="m140.93 85-16.35-28.33-1.93-3.34 8.66-15a3.323 3.323 0 0 0 0-3.34l-9.62-16.67c-.3-.51-.72-.93-1.22-1.22s-1.07-.45-1.67-.45H82.23l-8.66-15a3.33 3.33 0 0 0-2.89-1.67H51.43c-.59 0-1.17.16-1.66.45-.5.29-.92.71-1.22 1.22L32.19 29.98l-1.92 3.33H12.96c-.59 0-1.17.16-1.66.45-.5.29-.93.71-1.22 1.22L.45 51.66a3.323 3.323 0 0 0 0 3.34l18.28 31.67-8.66 15a3.32 3.32 0 0 0 0 3.34l9.62 16.67c.3.51.72.93 1.22 1.22s1.07.45 1.67.45h36.56l8.66 15a3.35 3.35 0 0 0 2.89 1.67h19.25a3.34 3.34 0 0 0 2.89-1.67l18.28-31.67h17.32c.6 0 1.17-.16 1.67-.45s.92-.71 1.22-1.22l9.62-16.67a3.323 3.323 0 0 0 0-3.34ZM51.44 3.33 61.07 20l-9.63 16.66h76.98l-9.62 16.66H45.67l-11.54-20zM57.21 120H22.58l9.63-16.67h19.25l-38.5-66.67h19.25l9.62 16.67L68.78 100l-11.55 20Zm61.59-33.34-9.62-16.67-38.49 66.67-9.63-16.67 9.63-16.66 26.94-46.67h23.1l17.32 30z"\n  />\n</svg>\n`;var l=window.React,h=({state:e,onClose:t})=>(l.useEffect(()=>{if(e.visible){let o=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=o}}},[e.visible]),e.visible?l.createElement("div",{className:"modal-overlay",onClick:t},l.createElement("div",{className:"modal-container",onClick:o=>o.stopPropagation()},l.createElement("div",{className:"modal-header"},l.createElement("span",{className:"modal-title font-mono"},e.fileName),l.createElement("button",{className:"modal-close",onClick:t,"aria-label":"Close"},"\\u2715")),l.createElement("pre",{className:"modal-content"},e.content))):null),x=()=>{let[e,t]=l.useState({visible:!1,content:"",fileName:""}),o=l.useCallback((n,p="temp")=>{t({visible:!0,content:n,fileName:p})},[]),i=l.useCallback(()=>{t(n=>({...n,visible:!1}))},[]);return{modalState:e,openModal:o,closeModal:i}};var z=window.React,b=()=>{let{modalState:e,openModal:t,closeModal:o}=x();return{platformContext:z.useMemo(()=>({platform:"web",postMessage:n=>{console.log("Posted message:",n)},onMessage:n=>(window.addEventListener("message",n),()=>window.removeEventListener("message",n)),openFile:n=>{console.log("Opening file:",n)},openTempFile:t,getResourceUrl:()=>{},features:{canOpenFile:!1,canOpenTempFile:!0,canCopy:!0}}),[t]),modalState:e,closeModal:o}};var a=({label:e,value:t,valueClass:o})=>t==null||t===""?null:React.createElement("div",{className:"metadata-item"},React.createElement("div",{className:"metadata-content"},React.createElement("span",{className:"metadata-label"},e),React.createElement("span",{className:`metadata-value ${o||""}`,title:typeof t=="string"?t:void 0},t)));var v=e=>!!e&&typeof e=="object",w=()=>{let e=document.getElementById("chat-data");if(!(e!=null&&e.textContent))return{};try{let t=JSON.parse(e.textContent);return t&&typeof t=="object"?t:{}}catch(t){return console.error("Failed to parse chat data.",t),{}}};var y=e=>{if(!e)return"-";try{return new Date(e).toLocaleString("en-US",{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch(t){return e}},k=e=>{if(!e)return"-";try{let o=new Date(e).getTime();if(Number.isNaN(o))return"-";let n=Math.max(0,new Date().getTime()-o),p=Math.floor(n/1e3),c=Math.floor(p/60),d=Math.floor(c/60),s=Math.floor(d/24),m=Math.floor(s/7),g=Math.floor(s/30),u=Math.floor(s/365);return p<60?"just now":c<60?`${c} minute${c===1?"":"s"} ago`:d<24?`${d} hour${d===1?"":"s"} ago`:s<7?`${s} day${s===1?"":"s"} ago`:m<4?`${m} week${m===1?"":"s"} ago`:g<12?`${g} month${g===1?"":"s"} ago`:`${u} year${u===1?"":"s"} ago`}catch(t){return"-"}};var M=e=>{if(e!=null)return e>=1e6?`${(e/1e6).toFixed(e%1e6===0?0:1)}m`:e>=1e3?`${(e/1e3).toFixed(e%1e3===0?0:1)}k`:e.toString()};var T=({metadata:e})=>React.createElement("aside",{className:"metadata-sidebar"},React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"Session Info"),React.createElement(a,{label:"Session created",value:k(e.startTime)}),React.createElement(a,{label:"Project",value:e.cwd,valueClass:"multiline"}),e.gitRepo&&React.createElement(a,{label:"Repository",value:e.gitRepo}),e.gitBranch&&React.createElement(a,{label:"Branch",value:e.gitBranch}),e.model&&React.createElement(a,{label:"Model",value:e.model}),e.channel&&React.createElement(a,{label:"Channel",value:e.channel})),React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"Statistics"),React.createElement(a,{label:"Prompts",value:e.promptCount}),e.contextUsagePercent!==void 0&&e.contextWindowSize!==void 0&&React.createElement(a,{label:"Context",value:`${e.contextUsagePercent>100?">100":e.contextUsagePercent}% of ${M(e.contextWindowSize)}`,valueClass:e.contextUsagePercent>100?"text-red":void 0}),e.totalTokens!==void 0&&React.createElement(a,{label:"Tokens",value:e.totalTokens.toLocaleString()})),React.createElement("div",{className:"metadata-section"},React.createElement("h3",{className:"metadata-section-title"},"File Operations"),e.filesWritten!==void 0&&e.filesWritten>0&&React.createElement(a,{label:"Files modified",value:e.filesWritten}),e.linesAdded!==void 0&&e.linesAdded>0&&React.createElement(a,{label:"Added",value:`+${e.linesAdded}`,valueClass:"text-green"}),e.linesRemoved!==void 0&&e.linesRemoved>0&&React.createElement(a,{label:"Removed",value:`-${e.linesRemoved}`,valueClass:"text-red"}),(e.filesWritten===void 0||e.filesWritten===0)&&(e.linesAdded===void 0||e.linesAdded===0)&&(e.linesRemoved===void 0||e.linesRemoved===0)&&React.createElement("p",{className:"metadata-item metadata-item-empty"},"No file changes")),React.createElement("div",{className:"metadata-section metadata-section-small"},React.createElement(a,{label:"Session ID",value:e.sessionId,valueClass:"font-mono"}),React.createElement(a,{label:"Export Time",value:y(e.exportTime)})));var $=()=>React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true"},React.createElement("circle",{cx:"12",cy:"12",r:"4"}),React.createElement("path",{d:"M12 2v2"}),React.createElement("path",{d:"M12 20v2"}),React.createElement("path",{d:"m4.93 4.93 1.41 1.41"}),React.createElement("path",{d:"m17.66 17.66 1.41 1.41"}),React.createElement("path",{d:"M2 12h2"}),React.createElement("path",{d:"M20 12h2"}),React.createElement("path",{d:"m6.34 17.66-1.41 1.41"}),React.createElement("path",{d:"m19.07 4.93-1.41 1.41"})),D=()=>React.createElement("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true"},React.createElement("path",{d:"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"})),C=({theme:e,onToggle:t})=>{let o=e==="light",i=o?"Switch to dark theme":"Switch to light theme";return React.createElement("button",{type:"button",className:"theme-toggle","aria-label":i,"aria-pressed":o,title:i,onClick:t},React.createElement(o?D:$,null))};var L=window.React,{useCallback:j,useEffect:I,useState:W}=L,N="qwen-export-theme",R=e=>e==="light"||e==="dark",F=()=>{try{let e=window.localStorage.getItem(N);if(R(e))return e}catch(e){}return"dark"},O=e=>{let t=document.documentElement;t.classList.toggle("light",e==="light"),t.classList.toggle("dark",e==="dark")},S=()=>{let[e,t]=W(F);I(()=>{O(e);try{window.localStorage.setItem(N,e)}catch(i){}},[e]);let o=j(()=>{t(i=>i==="light"?"dark":"light")},[]);return{theme:e,toggleTheme:o}};var A=window.ReactDOM,r=window.React,{ChatViewer:U,PlatformProvider:V}=QwenCodeWebUI,B=f?f.replace(/<svg([^>]*)>/,\'<svg$1><defs><linearGradient id="qwen-logo-gradient" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#60a5fa" /><stop offset="100%" stop-color="#a855f7" /></linearGradient></defs>\').replace(/fill="[^"]*"/,\'fill="url(#qwen-logo-gradient)"\'):f,H=()=>{let e=w(),o=(Array.isArray(e.messages)?e.messages:[]).filter(v).filter(m=>m.type!=="system"),i=e.metadata,{platformContext:n,modalState:p,closeModal:c}=b(),{theme:d,toggleTheme:s}=S();return r.createElement("div",{className:"page-wrapper"},r.createElement("header",{className:"header"},r.createElement("div",{className:"header-left"},r.createElement("div",{className:"logo-icon","aria-hidden":"true",dangerouslySetInnerHTML:{__html:B}}),r.createElement("div",{className:"logo"},r.createElement("div",{className:"logo-text","data-text":"QWEN"},r.createElement("span",{className:"logo-text-inner"},"QWEN")))),r.createElement("div",{className:"header-right"},r.createElement(C,{theme:d,onToggle:s}))),r.createElement("div",{className:"content-wrapper"},r.createElement("div",{className:"chat-container"},r.createElement(V,{value:n},r.createElement(U,{messages:o,autoScroll:!1,theme:d}))),i&&r.createElement(T,{metadata:i})),r.createElement(h,{state:p,onClose:c}))},E=document.getElementById("app");E?A.createRoot(E).render(r.createElement(H,null)):console.error("App container not found.");})();;\n    </script>\n  </body>\n</html>\n';

// packages/cli/src/ui/utils/export/formatters/html.ts
function escapeJsonForHtml(json) {
  return json.replace(/<\/script/gi, "<\\/script").replace(/&/g, "\\u0026").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
}
__name(escapeJsonForHtml, "escapeJsonForHtml");
function loadHtmlTemplate() {
  return HTML_TEMPLATE;
}
__name(loadHtmlTemplate, "loadHtmlTemplate");
function injectDataIntoHtmlTemplate(template, data) {
  const jsonData = JSON.stringify(data, null, 2);
  const escapedJsonData = escapeJsonForHtml(jsonData);
  const idAttribute = 'id="chat-data"';
  const idIndex = template.indexOf(idAttribute);
  if (idIndex === -1) {
    return template;
  }
  const openTagStart = template.lastIndexOf("<script", idIndex);
  if (openTagStart === -1) {
    return template;
  }
  const openTagEnd = template.indexOf(">", idIndex);
  if (openTagEnd === -1) {
    return template;
  }
  const closeTagStart = template.indexOf("</script>", openTagEnd);
  if (closeTagStart === -1) {
    return template;
  }
  const lineStart = template.lastIndexOf("\n", openTagStart);
  const lineIndent = lineStart === -1 ? "" : template.slice(lineStart + 1, openTagStart);
  const indentedJson = escapedJsonData.split("\n").map((line) => `${lineIndent}${line}`).join("\n");
  const before = template.slice(0, openTagEnd + 1);
  const after = template.slice(closeTagStart);
  return `${before}
${indentedJson}
${after}`;
}
__name(injectDataIntoHtmlTemplate, "injectDataIntoHtmlTemplate");
function toHtml(sessionData) {
  const template = loadHtmlTemplate();
  return injectDataIntoHtmlTemplate(template, sessionData);
}
__name(toHtml, "toHtml");

// packages/cli/src/ui/utils/export/formatters/json.ts
init_esbuild_shims();
function toJson(sessionData) {
  return JSON.stringify(sessionData, null, 2);
}
__name(toJson, "toJson");

// packages/cli/src/ui/utils/export/formatters/jsonl.ts
init_esbuild_shims();
function toJsonl(sessionData) {
  const lines = [];
  const sourceMetadata = sessionData.metadata;
  const metadata = {
    type: "session_metadata",
    sessionId: sessionData.sessionId,
    startTime: sessionData.startTime
  };
  if (sourceMetadata?.exportTime) {
    metadata["exportTime"] = sourceMetadata.exportTime;
  }
  if (sourceMetadata?.cwd) {
    metadata["cwd"] = sourceMetadata.cwd;
  }
  if (sourceMetadata?.gitRepo) {
    metadata["gitRepo"] = sourceMetadata.gitRepo;
  }
  if (sourceMetadata?.gitBranch) {
    metadata["gitBranch"] = sourceMetadata.gitBranch;
  }
  if (sourceMetadata?.model) {
    metadata["model"] = sourceMetadata.model;
  }
  if (sourceMetadata?.channel) {
    metadata["channel"] = sourceMetadata.channel;
  }
  if (sourceMetadata?.promptCount !== void 0) {
    metadata["promptCount"] = sourceMetadata.promptCount;
  }
  if (sourceMetadata?.contextUsagePercent !== void 0) {
    metadata["contextUsagePercent"] = sourceMetadata.contextUsagePercent;
  }
  if (sourceMetadata?.contextWindowSize !== void 0) {
    metadata["contextWindowSize"] = sourceMetadata.contextWindowSize;
  }
  if (sourceMetadata?.totalTokens !== void 0) {
    metadata["totalTokens"] = sourceMetadata.totalTokens;
  }
  if (sourceMetadata?.filesWritten !== void 0) {
    metadata["filesWritten"] = sourceMetadata.filesWritten;
  }
  if (sourceMetadata?.linesAdded !== void 0) {
    metadata["linesAdded"] = sourceMetadata.linesAdded;
  }
  if (sourceMetadata?.linesRemoved !== void 0) {
    metadata["linesRemoved"] = sourceMetadata.linesRemoved;
  }
  if (sourceMetadata?.uniqueFiles && sourceMetadata.uniqueFiles.length > 0) {
    metadata["uniqueFiles"] = sourceMetadata.uniqueFiles;
  }
  lines.push(JSON.stringify(metadata));
  for (const message of sessionData.messages) {
    lines.push(JSON.stringify(message));
  }
  return lines.join("\n");
}
__name(toJsonl, "toJsonl");

// packages/cli/src/ui/utils/export/utils.ts
init_esbuild_shims();
function generateExportFilename(extension) {
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
  return `qwen-code-export-${timestamp}.${extension}`;
}
__name(generateExportFilename, "generateExportFilename");

// packages/cli/src/ui/utils/export/index.ts
init_esbuild_shims();

export {
  GITHUB_WORKFLOW_PATHS,
  SetupGithubError,
  setupGithub,
  MessageEmitter,
  PlanEmitter,
  ToolCallEmitter,
  HistoryReplayer,
  collectSessionData,
  normalizeSessionData,
  toMarkdown,
  INSIGHT_JS,
  INSIGHT_CSS,
  toHtml,
  toJson,
  toJsonl,
  generateExportFilename
};
/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2025 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2025 Qwen
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @license
 * Copyright 2025 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * This file is code-generated; do not edit manually.
 */
/**
 * @license
 * Copyright 2025 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 *
 * This HTML template is code-generated; do not edit manually.
 */
