// Force strict mode and setup for ESM
"use strict";
import {
  sanitizeTerminalText
} from "./chunk-4NFY2S7N.js";
import {
  formatHistoryGapNotice
} from "./chunk-5LS57ZI3.js";
import {
  isGoalStatusKind,
  isTerminalGoalStatusKind
} from "./chunk-EKTCKZV5.js";
import {
  loadUndici
} from "./chunk-3Z43GZUQ.js";
import {
  getActiveGoal,
  registerGoalHook,
  setGoalTerminalObserver,
  setLastGoalTerminal,
  unregisterGoalHook
} from "./chunk-VDNAD6JC.js";
import {
  apiActivityTracker,
  formatVisionBridgeNoticeDisplay,
  isVisionBridgeNoticeDisplay
} from "./chunk-N7ZZBTIU.js";
import {
  ToolNames
} from "./chunk-CFDR3GNL.js";
import {
  createDebugLogger
} from "./chunk-3RXUYQJI.js";
import {
  writeStderrLine,
  writeStderrLineSafe
} from "./chunk-OWAK7LMW.js";
import {
  init_esbuild_shims
} from "./chunk-5O2XNYP6.js";
import {
  __name
} from "./chunk-J2S4EL5Y.js";

// packages/cli/src/ui/utils/restoreGoal.ts
init_esbuild_shims();
function findGoalToRestore(history) {
  for (let i = history.length - 1; i >= 0; i--) {
    const item = history[i];
    if (item?.type !== "goal_status" /* GOAL_STATUS */) continue;
    const goal = item;
    if (goal.kind !== "set" && goal.kind !== "checking") return null;
    const setAt = goal.setAt ?? findSetAtOfRun(history, i);
    return {
      condition: goal.condition,
      iterations: goal.iterations ?? 0,
      ...setAt !== void 0 ? { setAt } : {}
    };
  }
  return null;
}
__name(findGoalToRestore, "findGoalToRestore");
function findSetAtOfRun(history, startIndex) {
  const start = history[startIndex];
  const condition = start?.condition;
  for (let i = startIndex - 1; i >= 0; i--) {
    const item = history[i];
    if (item?.type !== "goal_status" /* GOAL_STATUS */) continue;
    const goal = item;
    if (goal.kind !== "set" && goal.kind !== "checking") return void 0;
    if (goal.condition !== condition) return void 0;
    if (goal.setAt !== void 0) return goal.setAt;
  }
  return void 0;
}
__name(findSetAtOfRun, "findSetAtOfRun");
function findLastTerminalGoal(history) {
  for (let i = history.length - 1; i >= 0; i--) {
    const item = history[i];
    if (item?.type !== "goal_status" /* GOAL_STATUS */) continue;
    const goal = item;
    if (!isTerminalGoalStatusKind(goal.kind)) continue;
    return {
      kind: goal.kind,
      condition: goal.condition,
      iterations: goal.iterations ?? 0,
      durationMs: goal.durationMs ?? 0,
      lastReason: goal.lastReason
    };
  }
  return null;
}
__name(findLastTerminalGoal, "findLastTerminalGoal");
function finiteNumber(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
}
__name(finiteNumber, "finiteNumber");
function isTranscriptItemRecord(item) {
  return typeof item === "object" && item !== null && !Array.isArray(item);
}
__name(isTranscriptItemRecord, "isTranscriptItemRecord");
function parseGoalStatusItem(item) {
  if (!isTranscriptItemRecord(item)) return null;
  if (item["type"] !== "goal_status" /* GOAL_STATUS */) return null;
  const kind = item["kind"];
  const condition = item["condition"];
  if (!isGoalStatusKind(kind) || typeof condition !== "string") return null;
  const iterations = finiteNumber(item["iterations"]);
  const setAt = finiteNumber(item["setAt"]);
  const durationMs = finiteNumber(item["durationMs"]);
  const lastReason = typeof item["lastReason"] === "string" ? item["lastReason"] : void 0;
  return {
    type: "goal_status" /* GOAL_STATUS */,
    kind,
    condition,
    ...iterations !== void 0 ? { iterations } : {},
    ...setAt !== void 0 ? { setAt } : {},
    ...durationMs !== void 0 ? { durationMs } : {},
    ...lastReason !== void 0 ? { lastReason } : {}
  };
}
__name(parseGoalStatusItem, "parseGoalStatusItem");
function collectGoalStatusItemsFromRecords(records) {
  const items = [];
  for (const record of records) {
    if (record.type !== "system" || record.subtype !== "slash_command") {
      continue;
    }
    const payload = record.systemPayload;
    if (payload?.phase !== "result") continue;
    const raws = payload.outputHistoryItems;
    if (!Array.isArray(raws)) continue;
    for (const raw of raws) {
      const item = parseGoalStatusItem(raw);
      if (item) items.push(item);
    }
  }
  return items;
}
__name(collectGoalStatusItemsFromRecords, "collectGoalStatusItemsFromRecords");
function goalTerminalEventToHistoryItem(event) {
  return {
    type: "goal_status" /* GOAL_STATUS */,
    kind: event.kind,
    condition: event.condition,
    iterations: event.iterations,
    durationMs: event.durationMs,
    lastReason: event.lastReason ?? event.systemMessage
  };
}
__name(goalTerminalEventToHistoryItem, "goalTerminalEventToHistoryItem");
function recordGoalStatusItem(config, item, rawCommand = "/goal") {
  try {
    const recording = config.getChatRecordingService?.();
    if (!recording) {
      writeStderrLineSafe(
        `qwen: no chat recording service; goal_status (kind=${item.kind}) will not survive a resume.`
      );
      return;
    }
    recording.recordSlashCommand({
      phase: "result",
      rawCommand,
      outputHistoryItems: [{ ...item }]
    });
  } catch (error) {
    writeStderrLineSafe(
      `qwen: failed to record goal_status (kind=${item.kind}): ${error}`
    );
  }
}
__name(recordGoalStatusItem, "recordGoalStatusItem");
function installGoalTerminalObserver(args) {
  const { sessionId, config, addItem } = args;
  setGoalTerminalObserver(sessionId, (event) => {
    const item = goalTerminalEventToHistoryItem(event);
    addItem(item, Date.now());
    recordGoalStatusItem(config, item);
  });
}
__name(installGoalTerminalObserver, "installGoalTerminalObserver");
function goalRestoreBlockedBy(config) {
  if (!config.isTrustedFolder()) return "untrusted-folder";
  if (config.getDisableAllHooks()) return "hooks-disabled";
  if (!config.getHookSystem()) return "no-hook-system";
  return null;
}
__name(goalRestoreBlockedBy, "goalRestoreBlockedBy");
function goalConditionBlockedBy(condition) {
  if (condition.length === 0) return "condition-invalid";
  return null;
}
__name(goalConditionBlockedBy, "goalConditionBlockedBy");
function restoreGoalFromHistory(history, config, addItem) {
  const sessionId = config.getSessionId();
  const lastTerminal = findLastTerminalGoal(history);
  setLastGoalTerminal(sessionId, lastTerminal ?? void 0);
  const restorable = findGoalToRestore(history);
  if (restorable === null) {
    unregisterGoalHook(config, sessionId);
    return { restored: false };
  }
  const blockedBy = goalRestoreBlockedBy(config);
  if (blockedBy) {
    unregisterGoalHook(config, sessionId);
    return { restored: false, blockedBy };
  }
  if (goalConditionBlockedBy(restorable.condition)) {
    writeStderrLineSafe(
      `qwen: refusing to restore a goal for session ${sessionId}: the condition is empty.`
    );
    unregisterGoalHook(config, sessionId);
    return { restored: false, blockedBy: "condition-invalid" };
  }
  registerGoalHook({
    config,
    sessionId,
    condition: restorable.condition,
    tokensAtStart: 0,
    // Resume the iteration count so MAX_GOAL_ITERATIONS is a cross-resume cap,
    // not a per-resume one.
    initialIterations: restorable.iterations,
    // Likewise the start time: without it every reload restarts the clock, and
    // `GET /goals` reports a long-running goal as freshly started.
    ...restorable.setAt !== void 0 ? { initialSetAt: restorable.setAt } : {}
  });
  if (addItem) {
    installGoalTerminalObserver({ sessionId, config, addItem });
  }
  return { restored: true, condition: restorable.condition };
}
__name(restoreGoalFromHistory, "restoreGoalFromHistory");

// packages/cli/src/services/setup-github.ts
init_esbuild_shims();
import { promises as fsp } from "node:fs";
import * as path from "node:path";

// packages/cli/src/utils/gitUtils.ts
init_esbuild_shims();
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 dispatcher = proxy ? new (await loadUndici()).ProxyAgent(proxy) : void 0;
    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,
      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;
  }
};
function isWorkspaceGenerationClosed(error) {
  return Boolean(
    error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
  );
}
__name(isWorkspaceGenerationClosed, "isWorkspaceGenerationClosed");
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) {
        if (isWorkspaceGenerationClosed(error)) throw 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 (isWorkspaceGenerationClosed(error)) throw 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) {
    if (isWorkspaceGenerationClosed(error)) throw 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 (await loadUndici()).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/acp-bridge/src/transcript-replay.ts
init_esbuild_shims();

// packages/core/dist/src/goals/goal-wire.js
init_esbuild_shims();

// packages/core/dist/src/goals/goal-protocol.js
init_esbuild_shims();
var GOAL_STATE_VERSION = 2;

// packages/core/dist/src/goals/goal-reducer.js
init_esbuild_shims();
var MAX_BLOCKED_AUDIT_COUNT = 3;
function parseGoalStateRecordPayloadV2(value) {
  if (!isRecord(value) || !hasOnlyKeys(value, ["v", "cause", "snapshot", "blockedAudit"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalStateCause(value["cause"]) || !isBlockedAudit(value["blockedAudit"])) {
    return void 0;
  }
  const parsedSnapshot = parseGoalSnapshotV2(value["snapshot"]);
  return parsedSnapshot?.activity === "idle" ? {
    v: GOAL_STATE_VERSION,
    cause: value["cause"],
    snapshot: parsedSnapshot,
    ...value["blockedAudit"] ? { blockedAudit: structuredClone(value["blockedAudit"]) } : {}
  } : void 0;
}
__name(parseGoalStateRecordPayloadV2, "parseGoalStateRecordPayloadV2");
function parseGoalSnapshotV2(value) {
  if (!isRecord(value) || !hasOnlyKeys(value, ["v", "goal", "activity"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalActivity(value["activity"])) {
    return void 0;
  }
  if (value["goal"] === null) {
    return {
      v: GOAL_STATE_VERSION,
      goal: null,
      activity: value["activity"]
    };
  }
  const goal = parseGoalRecord(value["goal"]);
  return goal ? { v: GOAL_STATE_VERSION, goal, activity: value["activity"] } : void 0;
}
__name(parseGoalSnapshotV2, "parseGoalSnapshotV2");
function copyCursor(cursor) {
  return { recordId: cursor.recordId };
}
__name(copyCursor, "copyCursor");
function parseGoalRecord(value) {
  if (!isRecord(value) || !hasOnlyKeys(value, [
    "goalId",
    "revision",
    "objective",
    "status",
    "evidenceCursor",
    "turnCount",
    "activeTimeMs",
    "createdAt",
    "updatedAt",
    "lastReason"
  ]) || typeof value["goalId"] !== "string" || !value["goalId"] || !isNonNegativeInteger(value["revision"]) || value["revision"] === 0 || typeof value["objective"] !== "string" || !value["objective"].trim() || !isGoalStatus(value["status"]) || !isTranscriptCursor(value["evidenceCursor"]) || !isNonNegativeInteger(value["turnCount"]) || !isNonNegativeNumber(value["activeTimeMs"]) || !isFiniteNumber(value["createdAt"]) || !isFiniteNumber(value["updatedAt"]) || value["lastReason"] !== void 0 && typeof value["lastReason"] !== "string") {
    return void 0;
  }
  return {
    goalId: value["goalId"],
    revision: value["revision"],
    objective: value["objective"],
    status: value["status"],
    evidenceCursor: copyCursor(value["evidenceCursor"]),
    turnCount: value["turnCount"],
    activeTimeMs: value["activeTimeMs"],
    createdAt: value["createdAt"],
    updatedAt: value["updatedAt"],
    ...value["lastReason"] === void 0 ? {} : { lastReason: value["lastReason"] }
  };
}
__name(parseGoalRecord, "parseGoalRecord");
function isTranscriptCursor(value) {
  return isRecord(value) && hasOnlyKeys(value, ["recordId"]) && (typeof value["recordId"] === "string" || value["recordId"] === null);
}
__name(isTranscriptCursor, "isTranscriptCursor");
function isGoalStatus(value) {
  return value === "active" || value === "paused" || value === "blocked" || value === "usage_limited" || value === "complete";
}
__name(isGoalStatus, "isGoalStatus");
function isGoalActivity(value) {
  return value === "idle" || value === "running" || value === "verifying";
}
__name(isGoalActivity, "isGoalActivity");
function isGoalStateCause(value) {
  return value === "create" || value === "replace" || value === "edit" || value === "pause" || value === "resume" || value === "turn_finished" || value === "verifier_accept" || value === "verifier_reject" || value === "complete" || value === "blocked" || value === "usage_limited" || value === "clear" || value === "migrated";
}
__name(isGoalStateCause, "isGoalStateCause");
function isBlockedAudit(value) {
  return value === void 0 || isRecord(value) && hasOnlyKeys(value, ["fingerprint", "count", "turnIds"]) && typeof value["fingerprint"] === "string" && value["fingerprint"].length > 0 && isNonNegativeInteger(value["count"]) && value["count"] > 0 && value["count"] <= MAX_BLOCKED_AUDIT_COUNT && Array.isArray(value["turnIds"]) && value["turnIds"].length === value["count"] && value["turnIds"].every((turnId) => typeof turnId === "string" && turnId.length > 0);
}
__name(isBlockedAudit, "isBlockedAudit");
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
__name(isRecord, "isRecord");
function hasOnlyKeys(value, keys) {
  return Object.keys(value).every((key) => keys.includes(key));
}
__name(hasOnlyKeys, "hasOnlyKeys");
function isNonNegativeInteger(value) {
  return typeof value === "number" && Number.isInteger(value) && value >= 0;
}
__name(isNonNegativeInteger, "isNonNegativeInteger");
function isNonNegativeNumber(value) {
  return typeof value === "number" && Number.isFinite(value) && value >= 0;
}
__name(isNonNegativeNumber, "isNonNegativeNumber");
function isFiniteNumber(value) {
  return typeof value === "number" && Number.isFinite(value);
}
__name(isFiniteNumber, "isFiniteNumber");

// packages/core/dist/src/goals/goal-legacy-projection.js
init_esbuild_shims();
function projectGoalStateToLegacy(payload, previousGoal = null) {
  const snapshotGoal = payload.snapshot.goal;
  const displayGoal = snapshotGoal ?? previousGoal;
  const kind = legacyStatusKind(payload);
  const goalStatus = {
    type: "goal_status",
    kind,
    condition: displayGoal?.objective ?? "",
    ...displayGoal ? { iterations: displayGoal.turnCount } : {},
    ...displayGoal ? { setAt: displayGoal.createdAt } : {},
    ...displayGoal ? { durationMs: displayGoal.activeTimeMs } : {},
    ...displayGoal?.lastReason === void 0 ? {} : { lastReason: displayGoal.lastReason }
  };
  const terminalKind = kind === "achieved" || kind === "failed" || kind === "aborted" ? kind : void 0;
  return {
    activeGoal: snapshotGoal?.status === "active" ? {
      condition: snapshotGoal.objective,
      iterations: snapshotGoal.turnCount,
      setAt: snapshotGoal.createdAt,
      ...snapshotGoal.lastReason === void 0 ? {} : { lastReason: snapshotGoal.lastReason }
    } : null,
    goalStatus,
    goalTerminal: terminalKind && displayGoal ? {
      kind: terminalKind,
      condition: displayGoal.objective,
      iterations: displayGoal.turnCount,
      durationMs: displayGoal.activeTimeMs,
      ...displayGoal.lastReason === void 0 ? {} : { lastReason: displayGoal.lastReason }
    } : null
  };
}
__name(projectGoalStateToLegacy, "projectGoalStateToLegacy");
function legacyStatusKind(payload) {
  switch (payload.cause) {
    case "create":
    case "replace":
    case "edit":
    case "resume":
    case "migrated":
      return "set";
    case "complete":
      return "achieved";
    case "clear":
      return "cleared";
    case "pause":
      return "paused";
    case "blocked":
    case "usage_limited":
      return "aborted";
    case "turn_finished":
    case "verifier_accept":
    case "verifier_reject":
      return payload.snapshot.goal?.status === "complete" ? "achieved" : payload.snapshot.goal?.status === "blocked" || payload.snapshot.goal?.status === "usage_limited" ? "aborted" : "checking";
    default:
      return assertNever(payload.cause);
  }
}
__name(legacyStatusKind, "legacyStatusKind");
function assertNever(value) {
  throw new Error(`Unsupported Goal state cause: ${String(value)}`);
}
__name(assertNever, "assertNever");

// packages/core/dist/src/hooks/user-prompt-submit-context.js
init_esbuild_shims();
var USER_PROMPT_SUBMIT_CONTEXT_OPEN_TAG = "<qwen:user-prompt-submit-context>";
var USER_PROMPT_SUBMIT_CONTEXT_CLOSE_TAG = "</qwen:user-prompt-submit-context>";
function isUserPromptSubmitContextPartText(text) {
  const trimmed = text.trim();
  return trimmed.startsWith(USER_PROMPT_SUBMIT_CONTEXT_OPEN_TAG) && trimmed.endsWith(USER_PROMPT_SUBMIT_CONTEXT_CLOSE_TAG) && trimmed.length >= USER_PROMPT_SUBMIT_CONTEXT_OPEN_TAG.length + USER_PROMPT_SUBMIT_CONTEXT_CLOSE_TAG.length;
}
__name(isUserPromptSubmitContextPartText, "isUserPromptSubmitContextPartText");
function stripTrailingUserPromptSubmitContextPart(parts) {
  if (parts.length <= 1) {
    return parts;
  }
  const last = parts[parts.length - 1];
  if (!last || typeof last.text !== "string" || !isUserPromptSubmitContextPartText(last.text)) {
    return parts;
  }
  return parts.slice(0, -1);
}
__name(stripTrailingUserPromptSubmitContextPart, "stripTrailingUserPromptSubmitContextPart");

// packages/acp-bridge/src/transcript-replay.ts
var MISSING_TRANSCRIPT_TOOL_RESULT_MESSAGE = "Tool result missing from saved history; the previous run likely ended before this tool completed.";
var TRANSCRIPT_GOAL_STATUS_KINDS = /* @__PURE__ */ new Set([
  "set",
  "achieved",
  "cleared",
  "failed",
  "aborted",
  "checking"
]);
function isObjectRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
__name(isObjectRecord, "isObjectRecord");
function toTranscriptEpochMs(timestamp) {
  if (typeof timestamp === "number") {
    return Number.isFinite(timestamp) ? timestamp : void 0;
  }
  if (typeof timestamp !== "string") return void 0;
  const epochMs = new Date(timestamp).getTime();
  return Number.isFinite(epochMs) ? epochMs : void 0;
}
__name(toTranscriptEpochMs, "toTranscriptEpochMs");
function buildUpdateMeta(options) {
  const timestamp = toTranscriptEpochMs(options.timestamp);
  const sourceRecordIds = dedupeStrings(options.sourceRecordIds ?? []);
  const qwenTranscript = {
    ...sourceRecordIds.length > 0 ? { sourceRecordIds } : {},
    ...options.planToolCallId ? { planToolCallId: options.planToolCallId } : {}
  };
  const meta = {
    ...options.extra ?? {},
    ...timestamp !== void 0 ? { timestamp } : {},
    ...Object.keys(qwenTranscript).length > 0 ? { qwenTranscript } : {}
  };
  return Object.keys(meta).length > 0 ? meta : void 0;
}
__name(buildUpdateMeta, "buildUpdateMeta");
function createTranscriptMessageUpdate(options) {
  const meta = buildUpdateMeta(options);
  return {
    sessionUpdate: options.role === "user" ? "user_message_chunk" : options.thought ? "agent_thought_chunk" : "agent_message_chunk",
    content: { type: "text", text: options.text },
    ...meta ? { _meta: meta } : {}
  };
}
__name(createTranscriptMessageUpdate, "createTranscriptMessageUpdate");
function createTranscriptImageUpdate(options) {
  const meta = buildUpdateMeta(options);
  return {
    sessionUpdate: "user_message_chunk",
    content: { type: "image", data: options.data, mimeType: options.mimeType },
    ...meta ? { _meta: meta } : {}
  };
}
__name(createTranscriptImageUpdate, "createTranscriptImageUpdate");
function createTranscriptUsageUpdate(usageMetadata, options = {}) {
  const usage = {
    inputTokens: finiteNumber2(usageMetadata.promptTokenCount) ?? 0,
    outputTokens: finiteNumber2(usageMetadata.candidatesTokenCount) ?? 0,
    totalTokens: finiteNumber2(usageMetadata.totalTokenCount) ?? 0,
    ...finiteNumber2(usageMetadata.thoughtsTokenCount) !== void 0 ? { thoughtTokens: finiteNumber2(usageMetadata.thoughtsTokenCount) } : {},
    ...finiteNumber2(usageMetadata.cachedContentTokenCount) !== void 0 ? {
      cachedReadTokens: finiteNumber2(usageMetadata.cachedContentTokenCount)
    } : {}
  };
  const meta = buildUpdateMeta({
    ...options,
    extra: { usage, ...options.extra ?? {} }
  });
  return {
    sessionUpdate: "agent_message_chunk",
    content: { type: "text", text: options.text ?? "" },
    _meta: meta
  };
}
__name(createTranscriptUsageUpdate, "createTranscriptUsageUpdate");
function createTranscriptToolCallStartUpdate(options) {
  const provenance = resolveToolProvenance(options.toolName);
  return {
    sessionUpdate: options.asUpdate ? "tool_call_update" : "tool_call",
    toolCallId: options.callId,
    status: options.status ?? "pending",
    title: options.metadata.title,
    content: [],
    locations: [...options.metadata.locations],
    kind: options.metadata.kind,
    rawInput: options.args ?? {},
    _meta: buildUpdateMeta({
      ...options,
      extra: {
        toolName: options.toolName,
        provenance: provenance.provenance,
        ...provenance.serverId ? { serverId: provenance.serverId } : {},
        ...options.extra ?? {}
      }
    })
  };
}
__name(createTranscriptToolCallStartUpdate, "createTranscriptToolCallStartUpdate");
function createTranscriptToolCallResultUpdate(options) {
  const provenance = resolveToolProvenance(options.toolName);
  const content = buildToolResultContent(options);
  const update = {
    sessionUpdate: "tool_call_update",
    toolCallId: options.callId,
    status: options.success ? "completed" : "failed",
    content,
    _meta: buildUpdateMeta({
      ...options,
      extra: {
        toolName: options.toolName,
        provenance: provenance.provenance,
        ...provenance.serverId ? { serverId: provenance.serverId } : {},
        ...options.artifacts && options.artifacts.length > 0 ? { artifacts: options.artifacts } : {},
        ...options.extra ?? {}
      }
    })
  };
  if (options.resultDisplay !== void 0 && !isTruncatedSessionDiffDisplay(options.resultDisplay)) {
    update["rawOutput"] = options.resultDisplay;
  }
  return update;
}
__name(createTranscriptToolCallResultUpdate, "createTranscriptToolCallResultUpdate");
function createTranscriptPlanUpdate(todos, cumulativeUsage, options = {}) {
  const meta = buildUpdateMeta({
    ...options,
    extra: {
      ...cumulativeUsage ? { stats: { ...cumulativeUsage } } : {},
      ...options.todoPlanId ? { qwenTodoPlan: { id: options.todoPlanId } } : {},
      ...options.extra ?? {}
    }
  });
  return {
    sessionUpdate: "plan",
    entries: todos.map((todo) => ({
      content: todo.content,
      priority: "medium",
      status: todo.status,
      ...todo.id || todo.blockedBy ? {
        _meta: {
          qwenTodo: {
            ...todo.id ? { id: todo.id } : {},
            ...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
          }
        }
      } : {}
    })),
    ...meta ? { _meta: meta } : {}
  };
}
__name(createTranscriptPlanUpdate, "createTranscriptPlanUpdate");
function extractTranscriptTodoPlan(resultDisplay, args) {
  const fromDisplay = extractTodoPlanFromDisplay(resultDisplay);
  if (fromDisplay) return fromDisplay;
  if (resultDisplay !== null && resultDisplay !== void 0) return null;
  return args && Array.isArray(args["todos"]) ? { todos: normalizeTodos(args["todos"]) } : null;
}
__name(extractTranscriptTodoPlan, "extractTranscriptTodoPlan");
function createTranscriptReplayMachine(options = {}) {
  return new DefaultTranscriptReplayMachine(options);
}
__name(createTranscriptReplayMachine, "createTranscriptReplayMachine");
var DefaultTranscriptReplayMachine = class {
  constructor(options) {
    this.options = options;
    const initialState = parseInitialState(
      options.initialState,
      options.onDiagnostic
    );
    this.usage = { ...initialState.cumulativeUsage };
    this.goalState = initialState.goalState;
    for (const pending of initialState.pendingToolCalls) {
      this.pendingToolCalls.set(pending.callId, pending);
      this.usedToolCallIds.add(pending.callId);
    }
    for (const gap of options.gaps ?? []) {
      if (!this.gapByChild.has(gap.childUuid)) {
        this.gapByChild.set(gap.childUuid, gap);
      }
    }
  }
  static {
    __name(this, "DefaultTranscriptReplayMachine");
  }
  pendingToolCalls = /* @__PURE__ */ new Map();
  usedToolCallIds = /* @__PURE__ */ new Set();
  gapByChild = /* @__PURE__ */ new Map();
  usage;
  finalized = false;
  goalState;
  *project(record) {
    if (this.finalized) {
      throw new Error(
        "Cannot project records after transcript replay finalize."
      );
    }
    let ordinal = 0;
    const emit = /* @__PURE__ */ __name((update) => ({
      sourceRecordId: record.uuid,
      ...record.timestamp ? { sourceTimestamp: record.timestamp } : {},
      emissionOrdinal: ordinal++,
      update
    }), "emit");
    const meta = {
      timestamp: record.timestamp,
      sourceRecordIds: [record.uuid]
    };
    const gap = this.gapByChild.get(record.uuid);
    if (gap) {
      yield emit(
        createTranscriptMessageUpdate({
          role: "assistant",
          text: this.formatGap(gap),
          ...meta,
          extra: { qwenDiscreteMessage: true }
        })
      );
    }
    switch (record.type) {
      case "user":
        yield* this.projectUserRecord(record, emit, meta);
        break;
      case "assistant":
        yield* this.projectAssistantRecord(record, emit, meta);
        break;
      case "tool_result":
        yield* this.projectToolResult(record, emit, meta);
        break;
      case "system":
        yield* this.projectSystemRecord(record, emit, meta);
        break;
      default:
        this.report(
          "unknown_record_or_part",
          "Skipped an unknown transcript record type.",
          record.uuid
        );
    }
  }
  *finalize() {
    if (this.finalized) return;
    this.finalized = true;
    let ordinal = 0;
    for (const pending of [...this.pendingToolCalls.values()]) {
      this.pendingToolCalls.delete(pending.callId);
      this.report(
        "missing_tool_result",
        "A transcript tool call has no persisted result.",
        pending.sourceRecordId
      );
      yield {
        sourceRecordId: pending.sourceRecordId,
        ...pending.sourceTimestamp ? { sourceTimestamp: pending.sourceTimestamp } : {},
        emissionOrdinal: ordinal++,
        update: createTranscriptToolCallResultUpdate({
          toolName: pending.toolName,
          callId: pending.callId,
          success: false,
          errorMessage: MISSING_TRANSCRIPT_TOOL_RESULT_MESSAGE,
          timestamp: pending.sourceTimestamp,
          sourceRecordIds: [pending.sourceRecordId]
        })
      };
    }
  }
  snapshot() {
    return {
      v: 1,
      pendingToolCalls: [...this.pendingToolCalls.values()].map((pending) => ({
        ...pending
      })),
      cumulativeUsage: { ...this.usage },
      ...this.goalState ? { goalState: this.goalState } : {}
    };
  }
  *projectUserRecord(record, emit, meta) {
    if (record.subtype === "goal_runtime" || record.subtype === "notification" || record.subtype === "cron" || record.subtype === "mid_turn_user_message") {
      const payload = isObjectRecord(record.systemPayload) ? record.systemPayload : void 0;
      const displayText = payload && typeof payload["displayText"] === "string" ? payload["displayText"] : void 0;
      const backgroundTask = payload && isObjectRecord(payload["backgroundTask"]) ? payload["backgroundTask"] : void 0;
      if (displayText) {
        const isNotification = record.subtype === "notification";
        yield emit(
          createTranscriptMessageUpdate({
            role: "user",
            text: displayText,
            ...meta,
            ...isNotification ? {
              extra: {
                source: "background_notification",
                qwenDiscreteMessage: true,
                ...backgroundTask ? { backgroundTask } : {}
              }
            } : record.subtype === "cron" ? { extra: { source: "cron" } } : {}
          })
        );
        return;
      }
      if (record.subtype !== "mid_turn_user_message") return;
    } else if (!record.subtype) {
      const payload = isObjectRecord(record.systemPayload) ? record.systemPayload : void 0;
      const displayText = payload && typeof payload["displayText"] === "string" ? payload["displayText"] : void 0;
      yield* this.projectMessageParts(
        displayText ? this.withUserPromptDisplayText(record, displayText) : this.withoutTrailingUserPromptSubmitContext(record),
        "user",
        emit,
        meta
      );
      return;
    }
    yield* this.projectMessageParts(record, "user", emit, meta);
  }
  /**
   * Drops a trailing message part that is entirely a tagged UserPromptSubmit
   * context block. Injection always appends after the user's own part(s), so
   * a sole matching part is treated as user-authored and kept.
   */
  withoutTrailingUserPromptSubmitContext(record) {
    const parts = record.message?.parts;
    if (!Array.isArray(parts)) {
      return record;
    }
    const nextParts = stripTrailingUserPromptSubmitContextPart(parts);
    if (nextParts === parts) {
      return record;
    }
    return {
      ...record,
      message: {
        ...record.message,
        parts: [...nextParts]
      }
    };
  }
  /**
   * Rebuilds a plain user record for display: strip trailing tagged hook
   * context, then replace every text part with a single `displayText` part at
   * the first text position so images keep their relative order.
   */
  withUserPromptDisplayText(record, displayText) {
    const stripped = this.withoutTrailingUserPromptSubmitContext(record);
    const parts = stripped.message?.parts;
    if (!Array.isArray(parts) || parts.length === 0) {
      return {
        ...stripped,
        message: {
          ...stripped.message,
          parts: [{ text: displayText }]
        }
      };
    }
    let replaced = false;
    const nextParts = [];
    for (const part of parts) {
      if (isObjectRecord(part) && typeof part["text"] === "string") {
        if (!replaced) {
          nextParts.push({ text: displayText });
          replaced = true;
        }
        continue;
      }
      nextParts.push(part);
    }
    if (!replaced) {
      nextParts.push({ text: displayText });
    }
    return {
      ...stripped,
      message: {
        ...stripped.message,
        parts: nextParts
      }
    };
  }
  *projectAssistantRecord(record, emit, meta) {
    const usageMetadata = isObjectRecord(record.usageMetadata) ? record.usageMetadata : void 0;
    let usageEmitted = false;
    const takeUsageUpdate = /* @__PURE__ */ __name(() => {
      if (!usageMetadata || usageEmitted) return void 0;
      usageEmitted = true;
      this.addUsage(usageMetadata);
      return createTranscriptUsageUpdate(usageMetadata, meta);
    }, "takeUsageUpdate");
    yield* this.projectMessageParts(
      record,
      "assistant",
      emit,
      meta,
      takeUsageUpdate
    );
    const trailingUsage = takeUsageUpdate();
    if (trailingUsage) yield emit(trailingUsage);
  }
  *projectMessageParts(record, role, emit, meta, beforeToolCall) {
    const parts = record.message?.parts;
    if (!parts) return;
    for (let partIndex = 0; partIndex < parts.length; partIndex += 1) {
      const part = parts[partIndex];
      if (!isObjectRecord(part)) {
        this.report(
          "malformed_part",
          "Skipped a malformed transcript message part.",
          record.uuid,
          `message.parts[${partIndex}]`
        );
        continue;
      }
      let recognized = false;
      if (typeof part["text"] === "string" && part["text"].length > 0) {
        recognized = true;
        yield emit(
          createTranscriptMessageUpdate({
            role,
            text: part["text"],
            thought: role === "assistant" && part["thought"] === true,
            ...meta
          })
        );
      }
      const inlineData = isObjectRecord(part["inlineData"]) ? part["inlineData"] : void 0;
      if (inlineData) {
        recognized = true;
        const data = inlineData["data"];
        const mimeType = inlineData["mimeType"];
        if (role === "user" && typeof data === "string" && typeof mimeType === "string" && mimeType.startsWith("image/")) {
          yield emit(createTranscriptImageUpdate({ data, mimeType, ...meta }));
        } else {
          this.report(
            "malformed_part",
            "Skipped an unsupported or malformed inline transcript part.",
            record.uuid,
            `message.parts[${partIndex}].inlineData`
          );
        }
      }
      const functionCall = isObjectRecord(part["functionCall"]) ? part["functionCall"] : void 0;
      if (functionCall) {
        recognized = true;
        const toolName = typeof functionCall["name"] === "string" ? functionCall["name"] : "";
        const args = isObjectRecord(functionCall["args"]) ? functionCall["args"] : {};
        if (!toolName) {
          this.report(
            "malformed_part",
            "Skipped a tool call without a tool name.",
            record.uuid,
            `message.parts[${partIndex}].functionCall`
          );
          continue;
        }
        const preToolUpdate = beforeToolCall?.();
        if (preToolUpdate) yield emit(preToolUpdate);
        if (toolName === "todo_write") continue;
        const explicitId = typeof functionCall["id"] === "string" && functionCall["id"].length > 0 ? functionCall["id"] : void 0;
        const callId = this.allocateToolCallId(
          explicitId ?? `qwen-replay-tool:${record.uuid}:${partIndex}`
        );
        const update = createTranscriptToolCallStartUpdate({
          toolName,
          callId,
          args,
          status: "in_progress",
          metadata: this.resolveToolMetadata(toolName, args, record.uuid),
          ...meta
        });
        yield emit(update);
        if (role === "assistant") {
          this.pendingToolCalls.set(callId, {
            callId,
            toolName,
            sourceRecordId: record.uuid,
            ...record.timestamp ? { sourceTimestamp: record.timestamp } : {}
          });
        }
      }
      if (!recognized && !("functionResponse" in part)) {
        this.report(
          "unknown_record_or_part",
          "Skipped an unknown transcript message part.",
          record.uuid,
          `message.parts[${partIndex}]`
        );
      }
    }
  }
  *projectToolResult(record, emit, meta) {
    const result = isObjectRecord(record.toolCallResult) ? record.toolCallResult : void 0;
    const toolName = extractToolName(record);
    if (!toolName) {
      this.report(
        "malformed_part",
        "A transcript tool result has no tool name.",
        record.uuid,
        "message.parts"
      );
    }
    const explicitCallId = extractToolResultCallId(record, result);
    const callId = explicitCallId ? this.allocateToolCallId(explicitCallId, true) : this.correlateResultCallId(toolName, record.uuid);
    this.pendingToolCalls.delete(callId);
    const resultDisplay = result?.["resultDisplay"];
    if (toolName === "todo_write") {
      const plan = extractTranscriptTodoPlan(resultDisplay);
      if (plan) {
        yield emit(
          createTranscriptPlanUpdate(plan.todos, this.usage, {
            ...meta,
            planToolCallId: callId,
            todoPlanId: plan.planId
          })
        );
      }
      return;
    }
    yield emit(
      createTranscriptToolCallResultUpdate({
        toolName,
        callId,
        success: result?.["status"] === void 0 ? !result?.["error"] : result["status"] === "success" && !result["error"],
        errorMessage: extractErrorMessage(result?.["error"]),
        message: record.message?.parts,
        resultDisplay,
        artifacts: Array.isArray(result?.["artifacts"]) ? result["artifacts"] : void 0,
        contentPrefix: this.buildToolResultContentPrefix(
          resultDisplay,
          record.uuid
        ),
        ...meta
      })
    );
    if (isTaskExecutionDisplay(resultDisplay)) {
      const usage = usageFromTaskExecution(resultDisplay);
      if (Object.keys(usage).length > 0) {
        this.addUsage(usage);
        yield emit(createTranscriptUsageUpdate(usage, meta));
      }
    }
  }
  *projectSystemRecord(record, emit, meta) {
    if (record.subtype === "goal_state") {
      const payload2 = parseGoalStateRecordPayloadV2(record.systemPayload);
      if (!payload2) {
        this.report(
          "malformed_goal_state",
          "Skipped a malformed Goal state transcript record.",
          record.uuid,
          "systemPayload"
        );
        return;
      }
      const projection = projectGoalStateToLegacy(
        payload2,
        this.goalState?.goal ?? null
      );
      this.goalState = payload2.snapshot;
      const { type: _type, ...goalStatus } = projection.goalStatus;
      yield emit(
        createTranscriptMessageUpdate({
          role: "assistant",
          text: "",
          ...meta,
          extra: {
            goalState: payload2.snapshot,
            goalStatus,
            ...projection.goalTerminal ? { goalTerminal: projection.goalTerminal } : {},
            "qwen.session.recordId": record.uuid
          }
        })
      );
      return;
    }
    if (record.subtype !== "slash_command") return;
    const payload = isObjectRecord(record.systemPayload) ? record.systemPayload : void 0;
    if (payload?.["phase"] !== "result") return;
    const items = Array.isArray(payload["outputHistoryItems"]) ? payload["outputHistoryItems"] : [];
    for (const item of items) {
      const goalStatus = parseTranscriptGoalStatus(item);
      if (goalStatus) {
        if (goalStatus.condition.length === 0) {
          this.report(
            "malformed_part",
            "Skipped replay of a goal card whose condition is empty.",
            record.uuid,
            "systemPayload.outputHistoryItems.goalStatus.condition"
          );
        } else if (goalStatus.kind !== "checking") {
          yield emit(
            createTranscriptMessageUpdate({
              role: "assistant",
              text: "",
              ...meta,
              extra: { goalStatus }
            })
          );
        }
        continue;
      }
      if (!isObjectRecord(item) || typeof item["text"] !== "string") continue;
      yield emit(
        createTranscriptMessageUpdate({
          role: "assistant",
          text: item["text"].replace(/\n/g, "  \n"),
          ...meta,
          extra: { source: "slash_command" }
        })
      );
    }
  }
  addUsage(metadata) {
    this.usage.promptTokens += finiteNumber2(metadata["promptTokenCount"]) ?? 0;
    this.usage.candidateTokens += finiteNumber2(metadata["candidatesTokenCount"]) ?? 0;
    this.usage.cachedTokens += finiteNumber2(metadata["cachedContentTokenCount"]) ?? 0;
  }
  correlateResultCallId(toolName, recordId) {
    const candidates = [...this.pendingToolCalls.values()].filter(
      (pending) => pending.toolName === toolName
    );
    if (candidates.length === 1) return candidates[0].callId;
    this.report(
      "ambiguous_tool_call_correlation",
      "A tool result could not be matched to exactly one pending tool call.",
      recordId
    );
    return this.allocateToolCallId(`qwen-replay-tool:${recordId}:result`);
  }
  allocateToolCallId(candidate, reuse = false) {
    if (reuse && this.pendingToolCalls.has(candidate)) {
      this.usedToolCallIds.add(candidate);
      return candidate;
    }
    if (!this.usedToolCallIds.has(candidate)) {
      this.usedToolCallIds.add(candidate);
      return candidate;
    }
    let occurrence = 2;
    while (this.usedToolCallIds.has(`${candidate}:${occurrence}`)) {
      occurrence += 1;
    }
    const id = `${candidate}:${occurrence}`;
    this.usedToolCallIds.add(id);
    return id;
  }
  resolveToolMetadata(toolName, args, recordId) {
    try {
      return this.options.presentation?.resolveToolMetadata(toolName, args) ?? fallbackToolMetadata(toolName, args);
    } catch {
      this.report(
        "presentation_fallback",
        "Tool presentation metadata fell back to deterministic defaults.",
        recordId,
        void 0,
        false
      );
      return fallbackToolMetadata(toolName, args);
    }
  }
  formatGap(gap) {
    try {
      return this.options.presentation?.formatHistoryGap(gap) ?? "Some earlier messages are unavailable because the saved history is incomplete.";
    } catch {
      this.report(
        "presentation_fallback",
        "History gap presentation fell back to deterministic defaults.",
        gap.childUuid,
        void 0,
        false
      );
      return "Some earlier messages are unavailable because the saved history is incomplete.";
    }
  }
  buildToolResultContentPrefix(resultDisplay, recordId) {
    try {
      return this.options.presentation?.buildToolResultContentPrefix?.(
        resultDisplay
      ) ?? defaultToolResultContentPrefix(resultDisplay);
    } catch {
      this.report(
        "presentation_fallback",
        "Tool result content presentation fell back to deterministic defaults.",
        recordId,
        void 0,
        false
      );
      return defaultToolResultContentPrefix(resultDisplay);
    }
  }
  report(code, message, recordId, path2, affectsCompleteness = true) {
    this.options.onDiagnostic?.({
      code,
      severity: affectsCompleteness ? "warning" : "info",
      message,
      affectsCompleteness,
      ...recordId ? { recordId } : {},
      ...path2 ? { path: path2 } : {}
    });
  }
};
function parseTranscriptGoalStatus(value) {
  if (!isObjectRecord(value) || value["type"] !== "goal_status") {
    return void 0;
  }
  const kind = value["kind"];
  const condition = value["condition"];
  if (typeof kind !== "string" || !TRANSCRIPT_GOAL_STATUS_KINDS.has(kind) || typeof condition !== "string") {
    return void 0;
  }
  const iterations = finiteNumber2(value["iterations"]);
  const setAt = finiteNumber2(value["setAt"]);
  const durationMs = finiteNumber2(value["durationMs"]);
  const lastReason = typeof value["lastReason"] === "string" ? value["lastReason"] : void 0;
  return {
    kind,
    condition,
    ...iterations !== void 0 ? { iterations } : {},
    ...setAt !== void 0 ? { setAt } : {},
    ...durationMs !== void 0 ? { durationMs } : {},
    ...lastReason !== void 0 ? { lastReason } : {}
  };
}
__name(parseTranscriptGoalStatus, "parseTranscriptGoalStatus");
function defaultToolResultContentPrefix(resultDisplay) {
  if (!isObjectRecord(resultDisplay) || resultDisplay["type"] !== "vision_bridge_notice" || typeof resultDisplay["summary"] !== "string" || typeof resultDisplay["notice"] !== "string") {
    return [];
  }
  return [
    {
      type: "content",
      content: {
        type: "text",
        text: `${resultDisplay["summary"]}
${resultDisplay["notice"]}`
      }
    }
  ];
}
__name(defaultToolResultContentPrefix, "defaultToolResultContentPrefix");
function parseInitialState(value, onDiagnostic) {
  const empty = {
    v: 1,
    pendingToolCalls: [],
    cumulativeUsage: emptyUsage()
  };
  if (value === void 0) return empty;
  if (!isObjectRecord(value)) {
    throw new TypeError("Invalid transcript replay state.");
  }
  if ("v" in value && value["v"] !== 1) {
    throw new TypeError("Unsupported transcript replay state version.");
  }
  const rawPending = Array.isArray(value["pendingToolCalls"]) ? value["pendingToolCalls"] : [];
  const pendingToolCalls = rawPending.flatMap(
    (pending) => {
      if (!isObjectRecord(pending) || typeof pending["callId"] !== "string" || typeof pending["toolName"] !== "string" || typeof pending["sourceRecordId"] !== "string") {
        onDiagnostic?.({
          code: "invalid_replay_state",
          severity: "warning",
          message: "Dropped a malformed pending tool call from replay state.",
          affectsCompleteness: true
        });
        return [];
      }
      return [
        {
          callId: pending["callId"],
          toolName: pending["toolName"],
          sourceRecordId: pending["sourceRecordId"],
          ...typeof pending["sourceTimestamp"] === "string" ? { sourceTimestamp: pending["sourceTimestamp"] } : {}
        }
      ];
    }
  );
  const rawUsage = value.cumulativeUsage;
  const usage = isObjectRecord(rawUsage) ? rawUsage : {};
  const validUsage = finiteNumber2(usage["promptTokens"]) !== void 0 && finiteNumber2(usage["cachedTokens"]) !== void 0 && finiteNumber2(usage["candidateTokens"]) !== void 0 && finiteNumber2(usage["apiTimeMs"]) !== void 0;
  if (!validUsage) {
    onDiagnostic?.({
      code: "invalid_replay_state",
      severity: "warning",
      message: "Reset invalid cumulative usage in transcript replay state.",
      affectsCompleteness: true
    });
  }
  const rawGoalState = value["goalState"];
  const goalState = rawGoalState === void 0 ? void 0 : parseGoalSnapshotV2(rawGoalState);
  if (rawGoalState !== void 0 && !goalState) {
    onDiagnostic?.({
      code: "invalid_replay_state",
      severity: "warning",
      message: "Dropped a malformed Goal state from replay state.",
      affectsCompleteness: true
    });
  }
  return {
    v: 1,
    pendingToolCalls,
    cumulativeUsage: validUsage ? {
      promptTokens: usage["promptTokens"],
      cachedTokens: usage["cachedTokens"],
      candidateTokens: usage["candidateTokens"],
      apiTimeMs: usage["apiTimeMs"]
    } : emptyUsage(),
    ...goalState ? { goalState } : {}
  };
}
__name(parseInitialState, "parseInitialState");
function emptyUsage() {
  return {
    promptTokens: 0,
    cachedTokens: 0,
    candidateTokens: 0,
    apiTimeMs: 0
  };
}
__name(emptyUsage, "emptyUsage");
function fallbackToolMetadata(toolName, args) {
  const description = typeof args["description"] === "string" ? args["description"].trim() : "";
  return {
    title: description ? `${toolName}: ${description}` : toolName,
    locations: [],
    kind: "other"
  };
}
__name(fallbackToolMetadata, "fallbackToolMetadata");
function resolveToolProvenance(toolName) {
  if (toolName.startsWith("mcp__")) {
    const parts = toolName.split("__");
    if (parts.length >= 3 && parts[1]) {
      return { provenance: "mcp", serverId: parts[1] };
    }
  }
  return { provenance: "builtin" };
}
__name(resolveToolProvenance, "resolveToolProvenance");
function buildToolResultContent(options) {
  const prefix = [...options.contentPrefix ?? []];
  const diff = extractDiffContent(options.resultDisplay);
  if (diff) return [...prefix, diff];
  if (options.errorMessage) {
    return [
      ...prefix,
      {
        type: "content",
        content: { type: "text", text: options.errorMessage }
      }
    ];
  }
  const content = [...prefix];
  for (const part of options.message ?? []) {
    if (!isObjectRecord(part)) continue;
    if (typeof part["text"] === "string" && part["text"]) {
      content.push({
        type: "content",
        content: { type: "text", text: part["text"] }
      });
    }
    const response = isObjectRecord(part["functionResponse"]) ? part["functionResponse"] : void 0;
    const payload = response && isObjectRecord(response["response"]) ? response["response"] : void 0;
    if (!payload) continue;
    try {
      const output = payload["output"];
      const error = payload["error"];
      const text = typeof output === "string" ? output : typeof error === "string" ? error : JSON.stringify(payload);
      content.push({
        type: "content",
        content: { type: "text", text }
      });
    } catch {
    }
  }
  return content;
}
__name(buildToolResultContent, "buildToolResultContent");
function extractDiffContent(resultDisplay) {
  if (!isObjectRecord(resultDisplay)) return null;
  if (!("fileName" in resultDisplay) || !("newContent" in resultDisplay)) {
    return null;
  }
  if (isTruncatedSessionDiffDisplay(resultDisplay)) {
    return {
      type: "content",
      content: {
        type: "text",
        text: buildTruncatedDiffPreviewText(resultDisplay)
      }
    };
  }
  return {
    type: "diff",
    path: typeof resultDisplay["fileName"] === "string" ? resultDisplay["fileName"] : "",
    oldText: typeof resultDisplay["originalContent"] === "string" ? resultDisplay["originalContent"] : "",
    newText: typeof resultDisplay["newContent"] === "string" ? resultDisplay["newContent"] : ""
  };
}
__name(extractDiffContent, "extractDiffContent");
function isTruncatedSessionDiffDisplay(value) {
  return isObjectRecord(value) && value["truncatedForSession"] === true && "fileName" in value && "newContent" in value;
}
__name(isTruncatedSessionDiffDisplay, "isTruncatedSessionDiffDisplay");
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.` : "";
  return display["fileDiffTruncated"] === true ? `Full diff omitted from saved session history for ${fileName}.${fileDiffLength}` : `Saved session preview only for ${fileName}; full original and new file contents are unavailable.`;
}
__name(buildTruncatedDiffPreviewText, "buildTruncatedDiffPreviewText");
function extractToolName(record) {
  for (const part of record.message?.parts ?? []) {
    if (!isObjectRecord(part) || !isObjectRecord(part["functionResponse"])) {
      continue;
    }
    const name = part["functionResponse"]["name"];
    if (typeof name === "string") return name;
  }
  return "";
}
__name(extractToolName, "extractToolName");
function extractToolResultCallId(record, result) {
  if (typeof result?.["callId"] === "string" && result["callId"].length > 0) {
    return result["callId"];
  }
  for (const part of record.message?.parts ?? []) {
    if (!isObjectRecord(part) || !isObjectRecord(part["functionResponse"])) {
      continue;
    }
    const id = part["functionResponse"]["id"];
    if (typeof id === "string" && id.length > 0) return id;
  }
  return void 0;
}
__name(extractToolResultCallId, "extractToolResultCallId");
function extractTodoPlanFromDisplay(value) {
  if (isObjectRecord(value) && value["type"] === "todo_list") {
    return Array.isArray(value["todos"]) ? {
      ...typeof value["planId"] === "string" ? { planId: value["planId"] } : {},
      todos: normalizeTodos(value["todos"])
    } : null;
  }
  if (typeof value !== "string") return null;
  try {
    const parsed = JSON.parse(value);
    return isObjectRecord(parsed) && parsed["type"] === "todo_list" && Array.isArray(parsed["todos"]) ? {
      ...typeof parsed["planId"] === "string" ? { planId: parsed["planId"] } : {},
      todos: normalizeTodos(parsed["todos"])
    } : null;
  } catch {
    return null;
  }
}
__name(extractTodoPlanFromDisplay, "extractTodoPlanFromDisplay");
function normalizeTodos(values) {
  return values.flatMap((value) => {
    if (!isObjectRecord(value) || typeof value["content"] !== "string")
      return [];
    const status = value["status"];
    if (status !== "pending" && status !== "in_progress" && status !== "completed") {
      return [];
    }
    return [
      {
        ...typeof value["id"] === "string" ? { id: value["id"] } : {},
        content: value["content"],
        status,
        ...Array.isArray(value["blockedBy"]) && value["blockedBy"].every((dependency) => typeof dependency === "string") ? { blockedBy: value["blockedBy"] } : {}
      }
    ];
  });
}
__name(normalizeTodos, "normalizeTodos");
function isTaskExecutionDisplay(value) {
  return isObjectRecord(value) && value["type"] === "task_execution";
}
__name(isTaskExecutionDisplay, "isTaskExecutionDisplay");
function usageFromTaskExecution(display) {
  const summary = isObjectRecord(display["executionSummary"]) ? display["executionSummary"] : void 0;
  if (!summary) return {};
  return {
    ...finiteNumber2(summary["inputTokens"]) !== void 0 ? { promptTokenCount: summary["inputTokens"] } : {},
    ...finiteNumber2(summary["outputTokens"]) !== void 0 ? { candidatesTokenCount: summary["outputTokens"] } : {},
    ...finiteNumber2(summary["thoughtTokens"]) !== void 0 ? { thoughtsTokenCount: summary["thoughtTokens"] } : {},
    ...finiteNumber2(summary["cachedTokens"]) !== void 0 ? { cachedContentTokenCount: summary["cachedTokens"] } : {},
    ...finiteNumber2(summary["totalTokens"]) !== void 0 ? { totalTokenCount: summary["totalTokens"] } : {}
  };
}
__name(usageFromTaskExecution, "usageFromTaskExecution");
function finiteNumber2(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
}
__name(finiteNumber2, "finiteNumber");
function extractErrorMessage(value) {
  if (value instanceof Error) return value.message;
  if (!isObjectRecord(value)) return void 0;
  return typeof value["message"] === "string" ? value["message"] : void 0;
}
__name(extractErrorMessage, "extractErrorMessage");
function dedupeStrings(values) {
  return [...new Set(values.filter((value) => value.length > 0))];
}
__name(dedupeStrings, "dedupeStrings");

// 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 = {}) {
    await this.sendUpdate(
      createTranscriptMessageUpdate({
        role: "user",
        text,
        timestamp,
        ...options.source ? { extra: { source: options.source } } : {}
      })
    );
  }
  /**
   * 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) {
    await this.sendUpdate(
      createTranscriptMessageUpdate({
        role: "assistant",
        thought: true,
        text,
        timestamp,
        ...subagentMeta ? { extra: { ...subagentMeta } } : {}
      })
    );
  }
  /**
   * 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) {
    await this.sendUpdate(
      createTranscriptMessageUpdate({
        role: "assistant",
        text,
        timestamp,
        ...subagentMeta ? { extra: { ...subagentMeta } } : {}
      })
    );
  }
  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 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,
        usageMetadata.promptTokenCount
      );
      cumulative.candidateTokens = addFinite(
        cumulative.candidateTokens,
        usageMetadata.candidatesTokenCount
      );
      cumulative.cachedTokens = addFinite(
        cumulative.cachedTokens,
        usageMetadata.cachedContentTokenCount
      );
      cumulative.apiTimeMs = addFinite(cumulative.apiTimeMs, durationMs);
    }
    let activityMeta = {};
    if (typeof durationMs === "number") {
      const activity = apiActivityTracker.drain();
      activityMeta = {
        ...activity.errors > 0 ? { apiErrors: activity.errors } : {},
        ...activity.retries > 0 ? { apiRetries: activity.retries } : {}
      };
    }
    await this.sendUpdate(
      createTranscriptUsageUpdate(usageMetadata, {
        text,
        extra: {
          ...typeof durationMs === "number" ? { durationMs } : {},
          ...activityMeta,
          ...subagentMeta
        }
      })
    );
  }
  /**
   * 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);
  }
};

// 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 plan - Plan identity and todo items to send as plan entries
   */
  async emitPlan(plan, sourceCallId) {
    const cumulative = this.ctx.cumulativeUsage;
    await this.sendUpdate(
      createTranscriptPlanUpdate(plan.todos, cumulative, {
        planToolCallId: sourceCallId,
        todoPlanId: plan.planId
      })
    );
  }
  /**
   * 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 when no result display is available
   *
   * @param resultDisplay - The tool result display (object, string, or undefined)
   * @param args - The tool call arguments (fallback source)
   * @returns Plan snapshot if found, null otherwise
   */
  extractPlan(resultDisplay, args) {
    const plan = extractTranscriptTodoPlan(resultDisplay, args);
    if (!plan) return null;
    return {
      ...plan.planId ? { planId: plan.planId } : {},
      todos: plan.todos.map((todo, index) => ({
        id: todo.id ?? String(index),
        content: todo.content,
        status: todo.status,
        ...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
      }))
    };
  }
};

// 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/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);
    await this.sendUpdate(
      createTranscriptToolCallStartUpdate({
        toolName: params.toolName,
        callId: params.callId,
        status: params.status || "pending",
        args: params.args,
        metadata: { title, locations, kind },
        timestamp: params.timestamp,
        asUpdate: updatesPreparedCall,
        extra: {
          ...params.phase ? { phase: params.phase } : {},
          ...params.subagentMeta,
          provenance: provenance.provenance,
          ...provenance.serverId ? { serverId: provenance.serverId } : {}
        }
      })
    );
    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)) {
      if (params.subagentMeta) return;
      if (!params.success) return;
      const plan = this.planEmitter.extractPlan(
        params.resultDisplay,
        params.args
      );
      if (plan && (plan.todos.length > 0 || params.args && Array.isArray(params.args["todos"]))) {
        await this.planEmitter.emitPlan(plan, params.callId);
      }
      return;
    }
    this.preparedCallIds.delete(params.callId);
    const provenance = _ToolCallEmitter.resolveToolProvenance(
      params.toolName,
      params.subagentMeta
    );
    await this.sendUpdate(
      createTranscriptToolCallResultUpdate({
        toolName: params.toolName,
        callId: params.callId,
        success: params.success,
        message: params.message,
        resultDisplay: params.resultDisplay,
        errorMessage: params.error?.message,
        artifacts: params.artifacts,
        contentPrefix: buildToolResultContentPrefix(params.resultDisplay),
        timestamp: params.timestamp,
        extra: {
          ...params.subagentMeta,
          provenance: provenance.provenance,
          ...provenance.serverId ? { serverId: provenance.serverId } : {}
        }
      })
    );
  }
  /**
   * 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(
      createTranscriptToolCallResultUpdate({
        toolName,
        callId,
        success: false,
        errorMessage: error.message,
        extra: {
          ...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";
  }
};
function buildToolResultContentPrefix(resultDisplay) {
  if (!isVisionBridgeNoticeDisplay(resultDisplay)) return [];
  return [
    {
      type: "content",
      content: {
        type: "text",
        text: sanitizeTerminalText(
          formatVisionBridgeNoticeDisplay(resultDisplay)
        )
      }
    }
  ];
}
__name(buildToolResultContentPrefix, "buildToolResultContentPrefix");

// packages/cli/src/acp-integration/session/history-replayer.ts
init_esbuild_shims();
var GOAL_NOT_RESTORED_REASON = {
  "untrusted-folder": "Goal not restored: this folder is not trusted, so its Stop hook cannot run.",
  "hooks-disabled": "Goal not restored: hooks are disabled for this session.",
  "no-hook-system": "Goal not restored: the hook system is unavailable."
};
var HistoryReplayer = class {
  constructor(ctx, options = {}) {
    this.ctx = ctx;
    this.options = options;
    this.messageEmitter = new MessageEmitter(ctx);
    this.toolCallEmitter = new ToolCallEmitter(ctx);
    this.machine = this.createMachine();
  }
  static {
    __name(this, "HistoryReplayer");
  }
  messageEmitter;
  toolCallEmitter;
  options;
  machine;
  async replay(records, gaps) {
    try {
      await this.replayPage(records, {
        finalizeDangling: true,
        gaps
      });
      await this.supersedeUnrestorableGoal(records);
    } finally {
      this.setActiveRecordId(null);
    }
  }
  async replayPage(records, options = {}) {
    this.machine = this.createMachine(options);
    let replayError;
    try {
      for (const record of records) {
        for (const emission of this.machine.project(record)) {
          this.setActiveRecordId(
            emission.sourceRecordId,
            emission.sourceTimestamp
          );
          await this.sendUpdate(emission.update);
        }
      }
    } catch (error) {
      replayError = error;
    }
    let danglingError;
    if (options.finalizeDangling === true) {
      for (const emission of this.machine.finalize()) {
        this.setActiveRecordId(
          emission.sourceRecordId,
          emission.sourceTimestamp
        );
        try {
          await this.sendUpdate(emission.update);
        } catch (error) {
          danglingError ??= error;
        }
      }
    }
    const replay = this.machine.snapshot();
    this.copyCumulativeUsage(replay);
    const state = {
      pendingToolCalls: options.finalizeDangling === true ? [] : replay.pendingToolCalls.map(toLegacyPendingToolCall),
      replay
    };
    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 this.machine.snapshot().pendingToolCalls.map(toLegacyPendingToolCall);
  }
  getReplayState() {
    return this.machine.snapshot();
  }
  createMachine(options = {}) {
    const cumulative = this.ctx.cumulativeUsage;
    const initialState = {
      v: 1,
      pendingToolCalls: (options.pendingToolCalls ?? []).map(
        toPendingTranscriptToolCall
      ),
      cumulativeUsage: cumulative ? { ...cumulative } : {
        promptTokens: 0,
        cachedTokens: 0,
        candidateTokens: 0,
        apiTimeMs: 0
      },
      ...options.goalState ? { goalState: options.goalState } : {}
    };
    return createTranscriptReplayMachine({
      initialState,
      gaps: options.gaps,
      presentation: this.presentationAdapter(),
      onDiagnostic: /* @__PURE__ */ __name((diagnostic) => {
        if (diagnostic.code === "malformed_part" && diagnostic.path === "systemPayload.outputHistoryItems.goalStatus.condition") {
          writeStderrLineSafe(`qwen: ${diagnostic.message}`);
        }
      }, "onDiagnostic")
    });
  }
  presentationAdapter() {
    return {
      resolveToolMetadata: /* @__PURE__ */ __name((toolName, args) => this.toolCallEmitter.resolveToolMetadata(toolName, { ...args }), "resolveToolMetadata"),
      formatHistoryGap: /* @__PURE__ */ __name((gap) => formatHistoryGapNotice(gap), "formatHistoryGap"),
      buildToolResultContentPrefix
    };
  }
  async sendUpdate(update) {
    if (this.ctx.messageRewriter) {
      await this.ctx.messageRewriter.interceptUpdate(update);
      return;
    }
    await this.ctx.sendUpdate(update);
  }
  copyCumulativeUsage(state) {
    const cumulative = this.ctx.cumulativeUsage;
    if (!cumulative) return;
    cumulative.promptTokens = state.cumulativeUsage.promptTokens;
    cumulative.cachedTokens = state.cumulativeUsage.cachedTokens;
    cumulative.candidateTokens = state.cumulativeUsage.candidateTokens;
    cumulative.apiTimeMs = state.cumulativeUsage.apiTimeMs;
  }
  /**
   * Emits a trailing `cleared` card when the transcript ends on an active goal
   * that `restoreGoalFromHistory` is about to refuse.
   *
   * A client reads "there is an active goal" off the newest goal card it has
   * seen, so replaying a `set` card that no Stop hook will drive leaves the UI
   * claiming a goal is running when the loop is dead. The gates are pure
   * functions of `config`, so the answer is known here, before restore runs.
   *
   * This card is emitted, not recorded: the transcript keeps its `set` card, so
   * a later resume in a trusted folder (or with hooks re-enabled) restores the
   * goal instead of finding it destroyed. Emitting from inside replay is also
   * what puts the card *after* the `set` card — `loadSession` batches replay
   * updates into its response, and a notification sent afterwards would reach
   * the client first.
   *
   * Gated on `supersedeUnrestorableGoal`: only a resume registers a hook, and
   * only a resume has a `config` that answers trust and hook-policy questions.
   */
  async supersedeUnrestorableGoal(records) {
    if (!this.options.supersedeUnrestorableGoal) return;
    const active = findGoalToRestore(
      collectGoalStatusItemsFromRecords(records)
    );
    if (!active || goalConditionBlockedBy(active.condition)) return;
    if (!hasFullSessionContext(this.ctx)) return;
    const blockedBy = goalRestoreBlockedBy(this.ctx.config);
    if (!blockedBy) return;
    await this.messageEmitter.emitGoalStatus({
      kind: "cleared",
      condition: active.condition,
      iterations: active.iterations,
      ...active.setAt !== void 0 ? { setAt: active.setAt } : {},
      lastReason: GOAL_NOT_RESTORED_REASON[blockedBy]
    });
  }
  setActiveRecordId(recordId, timestamp) {
    this.ctx.setActiveRecordId?.(recordId, timestamp);
  }
};
function toPendingTranscriptToolCall(pending) {
  return {
    callId: pending.callId,
    toolName: pending.toolName,
    sourceRecordId: pending.recordId,
    ...pending.timestamp ? { sourceTimestamp: pending.timestamp } : {}
  };
}
__name(toPendingTranscriptToolCall, "toPendingTranscriptToolCall");
function toLegacyPendingToolCall(pending) {
  return {
    callId: pending.callId,
    toolName: pending.toolName,
    recordId: pending.sourceRecordId,
    ...pending.sourceTimestamp ? { timestamp: pending.sourceTimestamp } : {}
  };
}
__name(toLegacyPendingToolCall, "toLegacyPendingToolCall");

// packages/cli/src/ui/utils/export/collect.ts
init_esbuild_shims();
import { randomUUID } from "node:crypto";

// 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/ui/utils/export/collect.ts
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("./deferred-core-runtime-ZLN3NSHZ.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();

// packages/cli/src/utils/truncatedDiffPreview.ts
init_esbuild_shims();
function buildTruncatedDiffPreviewText2(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(buildTruncatedDiffPreviewText2, "buildTruncatedDiffPreviewText");

// packages/cli/src/ui/utils/export/normalize.ts
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 = extractDiffContent2(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 extractDiffContent2(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: buildTruncatedDiffPreviewText2(display)
          }
        }
      ];
    }
    return [
      {
        type: "diff",
        path: display["fileName"],
        oldText: display["originalContent"] ?? "",
        newText: display["newContent"]
      }
    ];
  }
  return null;
}
__name(extractDiffContent2, "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,O){"use strict";function J({data:t}){const{totalMessages:n=0,totalLinesAdded:l=0,totalLinesRemoved:r=0,totalFiles:a=0}=t,s=Object.keys(t.heatmap||{});let o=0;if(s.length>0){const c=s.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,"/-",r),e.createElement("div",{className:"stat-label"},"Lines")),e.createElement("div",{className:"stat"},e.createElement("div",{className:"stat-value"},a),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")))}/**\n * @license\n * Copyright 2026 Qwen Team\n * SPDX-License-Identifier: Apache-2.0\n */function D(t){const n=t.getFullYear(),l=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0");return`${n}-${l}-${r}`}function Y(t){const[n,l,r]=t.split("-").map(Number);return new Date(n,l-1,r)}function V({insights:t}){return e.createElement("div",{className:"grid gap-4 md:grid-cols-2 md:gap-6"},e.createElement(X,{activeHours:t.activeHours,cardClass:"glass-card p-6",sectionTitleClass:"text-lg font-semibold tracking-tight text-slate-900"}))}function X({activeHours:t,cardClass:n,sectionTitleClass:l}){const a=[{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}}),s=Math.max(...a.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"},a.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:`${s>0?o.total/s*100:0}%`,backgroundColor:o.color}}))))))}function Z({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(R,{heatmapData:t}))),e.createElement(ee,null))}function R({heatmapData:t}){const s=new Date,o=new Date(s);o.setFullYear(s.getFullYear()-1);const i=[],m=new Date(o);for(;m<=s;)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(),j=[];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&&(j.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,q=x+v*16,k=D(u),S=t[k]||0,I=g(S);return e.createElement("rect",{key:k,className:"heatmap-day",x:N,y:q,width:14,height:14,rx:"2",fill:I,"data-date":k,"data-count":S},e.createElement("title",null,k,": ",S," activities"))}),j.map((u,f)=>e.createElement("text",{key:f,x:u.x,y:"15",fontSize:"12",fill:"#64748b"},u.text)))}function ee(){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,r)=>l.startsWith("**")&&l.endsWith("**")&&l.length>=4?e.createElement("strong",{key:r},l.slice(2,-2)):l))}function H({text:t,label:n="Copy"}){const[l,r]=e.useState(!1),a=()=>{navigator.clipboard.writeText(t).then(()=>{r(!0),setTimeout(()=>r(!1),2e3)})};return e.createElement("button",{className:"copy-btn",onClick:a},l?"Copied!":n)}function te(t){return typeof t=="string"&&t.trim().length>0}function ne({qualitative:t,targetSections:n}){const{atAGlance:l}=t;if(!l)return null;const r=[{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(a=>te(a.body));return r.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"},r.map(a=>e.createElement("div",{key:a.key,className:"glance-section"},e.createElement("strong",null,a.label)," ",e.createElement(p,null,a.body),a.showLink&&e.createElement("a",{href:a.href,className:"see-more"},a.link)))))}function le({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 re({qualitative:t,topGoals:n,topTools:l}){const{projectAreas:r}=t,a=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(r==null?void 0:r.areas)&&r.areas.length>0&&e.createElement("div",{className:"project-areas mb-6"},r.areas.map((s,o)=>e.createElement("div",{key:o,className:"project-area"},e.createElement("div",{className:"area-header"},e.createElement("span",{className:"area-name"},s.name),e.createElement("span",{className:"area-count"},"~",s.session_count," sessions")),e.createElement("div",{className:"area-desc"},e.createElement(p,null,s.description))))),e.createElement("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, 1fr)",gap:"24px",marginBottom:"24px"}},n&&Object.keys(n).length>0&&e.createElement(M,{data:n,title:"What You Wanted",color:"#0ea5e9"}),a&&Object.keys(a).length>0&&e.createElement(M,{data:a,title:"Top Tools Used",color:"#6366f1"})))}function ae({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(V,{insights:n}),e.createElement(Z,{heatmap:n.heatmap})):null}function se({qualitative:t,primarySuccess:n,outcomes:l}){const r=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"),(r==null?void 0:r.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,r.intro)),r&&e.createElement("div",{className:"big-wins"},Array.isArray(r.impressive_workflows)&&r.impressive_workflows.map((a,s)=>e.createElement("div",{key:s,className:"big-win"},e.createElement("div",{className:"big-win-title"},a.title),e.createElement("div",{className:"big-win-desc"},e.createElement(p,null,a.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(M,{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(M,{data:l,title:"Outcomes",color:"#8b5cf6",allowedKeys:["fully_achieved","mostly_achieved","partially_achieved","not_achieved","unclear_from_transcript"]})))}function oe(t){return t==="unclear_from_transcript"?"Unclear":t.split("_").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}function M({data:t,title:n,color:l="#3b82f6",allowedKeys:r=null}){if(!t||Object.keys(t).length===0)return null;let a=Object.entries(t).filter(([,o])=>Number.isFinite(o)&&o!==0);if(r&&(a=a.filter(([o])=>r.includes(o))),a.sort((o,i)=>i[1]-o[1]),a=a.slice(0,10),a.length===0)return null;const s=Math.max(...a.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"}},a.map(([o,i])=>{const m=s>0?i/s*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"}},oe(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 ie({qualitative:t,satisfaction:n,friction:l}){const r=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"),(r==null?void 0:r.intro)&&e.createElement("p",{className:"section-intro"},e.createElement(p,null,r.intro)),r&&e.createElement("div",{className:"friction-categories"},Array.isArray(r.categories)&&r.categories.map((a,s)=>e.createElement("div",{key:s,className:"friction-category"},e.createElement("div",{className:"friction-title"},a.category),e.createElement("div",{className:"friction-desc"},e.createElement(p,null,a.description)),Array.isArray(a.examples)&&a.examples.length>0&&e.createElement("ul",{className:"friction-examples"},a.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(M,{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(M,{data:n,title:"Inferred Satisfaction (model-estimated)",color:"#10b981",allowedKeys:["happy","satisfied","likely_satisfied","dissatisfied","frustrated"]})))}function me({additions:t}){const[n,l]=e.useState(new Array(t.length).fill(!0)),[r,a]=e.useState(!1),s=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(()=>{a(!0),setTimeout(()=>a(!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 ${r?"copied":""}`,onClick:o,disabled:i===0},r?"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:()=>s(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(H,{text:m.addition}))))}function ce({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,r=Array.isArray(n.usage_patterns)&&n.usage_patterns.length>0;return!l&&!r?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(me,{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((a,s)=>e.createElement("div",{key:s,className:"feature-card"},e.createElement("div",{className:"feature-title"},a.feature),e.createElement("div",{className:"feature-oneliner"},e.createElement(p,null,a.one_liner)),e.createElement("div",{className:"feature-why"},e.createElement("strong",null,"Why for you:")," ",e.createElement(p,null,a.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"},a.example_code),e.createElement(H,{text:a.example_code})))))))),r&&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((a,s)=>e.createElement("div",{key:s,className:"pattern-card"},e.createElement("div",{className:"pattern-title"},a.title),e.createElement("div",{className:"pattern-summary"},e.createElement(p,null,a.suggestion)),e.createElement("div",{className:"pattern-detail"},e.createElement(p,null,a.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"},a.copyable_prompt),e.createElement(H,{text:a.copyable_prompt}))))))))}function de({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,r)=>e.createElement("div",{key:r,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(H,{text:l.copyable_prompt}))))))):null}function pe({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 ue={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 fe({data:t,theme:n="light"}){var h,T,u,f,C,_;const l=ue[n],{totalMessages:r=0,totalSessions:a=0,totalLinesAdded:s=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=>Y(S).getTime()),N=new Date(Math.min(...v)),q=new Date(Math.max(...v)),k=S=>D(S);x=`${k(N)} \u2014 ${k(q)}`}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,j=ge(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(z,{value:String(r),label:"Messages",theme:l}),e.createElement(z,{value:String(a),label:"Sessions",theme:l}),e.createElement(z,{value:`+${s}/-${o}`,label:"Lines Changed",small:!0,theme:l}),e.createElement(z,{value:String(i),label:"Files",theme:l}),e.createElement(z,{value:`${m}d`,label:"Streak",theme:l}),e.createElement(z,{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(xe,{cells:j})),e.createElement(Ee,{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(he,{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 ",D(new Date)),e.createElement("div",{style:{fontSize:"12px",color:l.textMuted}},"github.com/QwenLM/qwen-code")))}function z({value:t,label:n,small:l,theme:r}){return e.createElement("div",{style:{textAlign:"center"}},e.createElement("div",{style:{fontSize:l?"18px":"28px",fontWeight:700,color:r.textPrimary,lineHeight:1.2}},t),e.createElement("div",{style:{fontSize:"11px",color:r.textMuted,textTransform:"uppercase",letterSpacing:"0.05em",marginTop:"4px"}},n))}function he({activeHours:t,theme:n}){const r=[{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(s=>({...s,total:s.hours.reduce((o,i)=>o+(t[i]||0),0)})),a=Math.max(...r.map(s=>s.total),1);return e.createElement(e.Fragment,null,r.map(s=>{const o=a>0?s.total/a*100:0;return e.createElement("div",{key:s.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:s.color,display:"inline-block",flexShrink:0}}),e.createElement("span",{style:{color:n.textSecondary,fontWeight:500}},s.label),e.createElement("span",{style:{color:n.textMuted,fontSize:"11px"}},s.time)),e.createElement("span",{style:{color:n.textMuted,fontWeight:600}},s.total)),e.createElement("div",{style:{height:"6px",background:n.borderColor,borderRadius:"3px",overflow:"hidden"}},e.createElement("div",{style:{width:`${o}%`,height:"100%",backgroundColor:s.color,borderRadius:"3px"}})))}))}function ge(t,n){const l=new Date,a=26*7,s=new Date(l);s.setDate(s.getDate()-a+1),s.setDate(s.getDate()-s.getDay());const o=[],i=new Date(l);i.setDate(i.getDate()+(6-i.getDay()));const m=new Date(s);for(;m<=i;){const c=D(m),d=t[c]||0;o.push({color:ye(d,n)}),m.setDate(m.getDate()+1)}return o}function ye(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 xe({cells:t}){const l=Math.ceil(t.length/7),r=14,a=3,s=l*(r+a),o=7*(r+a);return e.createElement("svg",{width:s,height:o,viewBox:`0 0 ${s} ${o}`},t.map((i,m)=>{const c=Math.floor(m/7),d=m%7;return e.createElement("rect",{key:m,x:c*(r+a),y:d*(r+a),width:r,height:r,rx:2,fill:i.color})}))}function Ee({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 W(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 $(t){return Array.isArray(t)&&t.some(n=>b(n))}function ve({data:t}){var u,f,C,_,v,N,q,k,S,I,K,U;const[n,l]=e.useState("dark"),r=e.useRef(!1),a=async()=>{const F=document.getElementById("share-card");if(!F||!window.html2canvas){alert("Export functionality is not available.");return}try{const y=F.cloneNode(!0);y.style.position="fixed",y.style.left="-9999px",y.style.top="0",y.style.pointerEvents="none",document.body.appendChild(y);const P=await window.html2canvas(y,{scale:2,useCORS:!0,logging:!1,width:1200,height:y.scrollHeight});document.body.removeChild(y);const G=P.toDataURL("image/png"),L=document.createElement("a");L.href=G,L.download=`qwen-insights-card-${D(new Date)}.png`,L.click()}catch(y){console.error("Export card error:",y),alert("Failed to export card. Please try again.")}};e.useEffect(()=>{r.current&&(r.current=!1,a())},[n]);const s=F=>{F===n?a():(r.current=!0,l(F))};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(B=>Y(B)).map(B=>B.getTime()),P=new Date(Math.min(...y)),G=new Date(Math.max(...y)),L=B=>D(B);i=`${L(P)} to ${L(G)}`}const m=b((u=t.qualitative)==null?void 0:u.atAGlance),c=!!t.qualitative&&(b(t.qualitative.projectAreas)||W(t.topGoals)||W(t.topTools)),d=b((f=t.qualitative)==null?void 0:f.interactionStyle),g=!!t.qualitative&&(b(t.qualitative.impressiveWorkflows)||W(t.primarySuccess)||W(t.outcomes)),E=!!t.qualitative&&(b(t.qualitative.frictionPoints)||W(t.satisfaction)||W(t.friction)),x=!!t.qualitative&&($((C=t.qualitative.improvements)==null?void 0:C.Qwen_md_additions)||$((_=t.qualitative.improvements)==null?void 0:_.features_to_try)),A=!!t.qualitative&&$((v=t.qualitative.improvements)==null?void 0:v.usage_patterns),w=b((N=t.qualitative)==null?void 0:N.futureOpportunities),j=b((q=t.qualitative)==null?void 0:q.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(be,{onExport:s}))),m&&t.qualitative&&e.createElement(ne,{qualitative:t.qualitative,targetSections:T}),h.length>0&&e.createElement(le,{sections:h}),e.createElement(J,{data:t}),c&&t.qualitative&&e.createElement(re,{qualitative:t.qualitative,topGoals:t.topGoals,topTools:t.topTools}),d&&t.qualitative&&e.createElement(ae,{qualitative:t.qualitative,insights:t}),g&&e.createElement(se,{qualitative:t.qualitative,primarySuccess:(S=t.primarySuccess)!=null?S:{},outcomes:(I=t.outcomes)!=null?I:{}}),E&&e.createElement(ie,{qualitative:t.qualitative,satisfaction:(K=t.satisfaction)!=null?K:{},friction:(U=t.friction)!=null?U:{}}),(x||A)&&t.qualitative&&e.createElement(ce,{qualitative:t.qualitative}),w&&t.qualitative&&e.createElement(de,{qualitative:t.qualitative}),j&&t.qualitative&&e.createElement(pe,{qualitative:t.qualitative}),e.createElement(fe,{data:t,theme:n}))}function be({onExport:t}){const[n,l]=e.useState(!1),r=e.useRef(null);e.useEffect(()=>{if(!n)return;const s=o=>{r.current&&!r.current.contains(o.target)&&l(!1)};return document.addEventListener("mousedown",s),()=>document.removeEventListener("mousedown",s)},[n]);const a=s=>{l(!1),t(s)};return e.createElement("div",{className:"export-dropdown-wrapper",ref:r},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:()=>a("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:()=>a("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 Q=document.getElementById("react-root");Q&&window.INSIGHT_DATA&&O?O.createRoot(Q).render(e.createElement(ve,{data:window.INSIGHT_DATA})):console.error("Failed to mount React app:",{container:!!Q,data:!!window.INSIGHT_DATA,ReactDOM:!!O})})(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,
  createTranscriptMessageUpdate,
  MessageEmitter,
  PlanEmitter,
  ToolCallEmitter,
  collectGoalStatusItemsFromRecords,
  goalTerminalEventToHistoryItem,
  recordGoalStatusItem,
  installGoalTerminalObserver,
  restoreGoalFromHistory,
  HistoryReplayer,
  collectSessionData,
  normalizeSessionData,
  toMarkdown,
  INSIGHT_JS,
  INSIGHT_CSS,
  toHtml,
  toJson,
  toJsonl,
  generateExportFilename
};
/**
 * @license
 * Copyright 2026 Qwen Team
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 * @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 Code
 * 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.
 */
