'use strict';

var fs10 = require('fs');
var path = require('path');
var child_process = require('child_process');
var util = require('util');
require('fs/promises');
var os3 = require('os');
require('url');
var readline3 = require('readline');
var process$1 = require('process');
require('posthog-node');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var fs10__default = /*#__PURE__*/_interopDefault(fs10);
var path__default = /*#__PURE__*/_interopDefault(path);
var os3__default = /*#__PURE__*/_interopDefault(os3);
var readline3__default = /*#__PURE__*/_interopDefault(readline3);

// src/features/token-optimizer/infrastructure/config.ts
var DEFAULT_TOKEN_OPTIMIZER_STATE = {
  enabled: false
};
globalThis.__JU_HONG_E_TOKEN_OPTIMIZER_STATE__ ?? (globalThis.__JU_HONG_E_TOKEN_OPTIMIZER_STATE__ = {
  ...DEFAULT_TOKEN_OPTIMIZER_STATE
});

// src/platform/core/cancellation.ts
var USER_CANCELLED_ERROR_CODE = "JUHONG_E_USER_CANCELLED";
var USER_TERMINATED_ERROR_CODE = "JUHONG_E_USER_TERMINATED";
function createCancellationError(name, code, message) {
  const error = new Error(message);
  error.name = name;
  error.code = code;
  return error;
}
function hasCancellationErrorCode(error, code) {
  return Boolean(
    error && typeof error === "object" && "code" in error && error.code === code
  );
}
function createUserCancelledError(message = "\uC0AC\uC6A9\uC790\uAC00 \uD604\uC7AC \uC791\uC5C5\uC744 \uCDE8\uC18C\uD588\uC2B5\uB2C8\uB2E4.") {
  return createCancellationError("UserCancelledError", USER_CANCELLED_ERROR_CODE, message);
}
function isUserCancelledError(error) {
  return hasCancellationErrorCode(error, USER_CANCELLED_ERROR_CODE);
}
function createUserTerminatedError(message = "\uC0AC\uC6A9\uC790\uAC00 \uC138\uC158 \uC885\uB8CC\uB97C \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4.") {
  return createCancellationError("UserTerminatedError", USER_TERMINATED_ERROR_CODE, message);
}
function isUserTerminatedError(error) {
  return hasCancellationErrorCode(error, USER_TERMINATED_ERROR_CODE);
}
function runGitCommand(rootDir, command) {
  return child_process.execSync(command, {
    cwd: rootDir,
    encoding: "utf8",
    maxBuffer: 1024 * 1024 * 20,
    stdio: ["ignore", "pipe", "pipe"]
  }).trim();
}
function isGitRepository(rootDir) {
  try {
    runGitCommand(rootDir, "git rev-parse --show-toplevel");
    return true;
  } catch {
    return false;
  }
}
function captureWorkspaceSnapshot(rootDir) {
  if (!isGitRepository(rootDir)) {
    return {
      available: false,
      branch: "",
      diffNameStatus: "",
      diffStat: "",
      gitRoot: "",
      note: "\uD604\uC7AC \uC791\uC5C5 \uACBD\uB85C\uAC00 Git \uC800\uC7A5\uC18C\uAC00 \uC544\uB2D9\uB2C8\uB2E4.",
      recentCommits: [],
      statusLines: []
    };
  }
  const gitRoot = runGitCommand(rootDir, "git rev-parse --show-toplevel");
  const branch = runGitCommand(rootDir, "git branch --show-current");
  const statusOutput = runGitCommand(rootDir, "git status --short");
  const diffStat = runGitCommand(rootDir, "git diff --stat");
  const diffNameStatus = runGitCommand(rootDir, "git diff --name-status");
  const recentCommits = runGitCommand(rootDir, "git log --oneline -5");
  return {
    available: true,
    branch,
    diffNameStatus,
    diffStat,
    gitRoot,
    note: "",
    recentCommits: recentCommits ? recentCommits.split("\n").filter(Boolean) : [],
    statusLines: statusOutput ? statusOutput.split("\n").filter(Boolean) : []
  };
}
function statusLineToPath(statusLine) {
  const normalized = statusLine.trim();
  if (!normalized) {
    return "";
  }
  const pathValue = normalized.slice(3).split(" -> ").pop();
  return pathValue?.trim() || normalized;
}
function diffWorkspaceSnapshots(before, after) {
  const beforeSet = new Set(before.statusLines);
  const afterSet = new Set(after.statusLines);
  const beforeOnly = before.statusLines.filter((line) => !afterSet.has(line));
  const afterOnly = after.statusLines.filter((line) => !beforeSet.has(line));
  const touchedFiles = Array.from(
    new Set([...beforeOnly.map(statusLineToPath), ...afterOnly.map(statusLineToPath)].filter(Boolean))
  );
  return {
    afterOnly,
    beforeOnly,
    touchedFiles
  };
}
function formatCodeBlock(content, language = "") {
  return `\`\`\`${language}
${content || "(\uC5C6\uC74C)"}
\`\`\``;
}
function formatWorkspaceSnapshot(snapshot) {
  if (!snapshot.available) {
    return snapshot.note;
  }
  return [
    `- Git Root: \`${snapshot.gitRoot}\``,
    `- Branch: \`${snapshot.branch || "(detached)"}\``,
    "",
    "### git status --short",
    formatCodeBlock(snapshot.statusLines.join("\n")),
    "",
    "### git diff --stat",
    formatCodeBlock(snapshot.diffStat),
    "",
    "### git diff --name-status",
    formatCodeBlock(snapshot.diffNameStatus),
    "",
    "### \uCD5C\uADFC \uCEE4\uBC0B",
    formatCodeBlock(snapshot.recentCommits.join("\n"))
  ].join("\n");
}
function formatWorkspaceDelta(delta) {
  return [
    "### \uC0C8\uB85C \uAC10\uC9C0\uB41C \uC0C1\uD0DC",
    formatCodeBlock(delta.afterOnly.join("\n")),
    "",
    "### \uC0AC\uB77C\uC9C4 \uC774\uC804 \uC0C1\uD0DC",
    formatCodeBlock(delta.beforeOnly.join("\n")),
    "",
    "### \uC601\uD5A5 \uD30C\uC77C",
    formatCodeBlock(delta.touchedFiles.join("\n"))
  ].join("\n");
}
function safeExcerpt(content, limit = 3e3) {
  if (!content) {
    return "";
  }
  if (content.length <= limit) {
    return content;
  }
  return `${content.slice(0, limit)}
... (truncated ${content.length - limit} chars)`;
}
function stringifyUnknown(value) {
  if (value === void 0 || value === null) {
    return "";
  }
  if (typeof value === "string") {
    return value;
  }
  if (Buffer.isBuffer(value)) {
    return value.toString("utf8");
  }
  if (value instanceof Error) {
    return value.stack || value.message;
  }
  return util.inspect(value, { depth: 6, breakLength: 120 });
}
function getErrorSummary(error) {
  if (error instanceof Error) {
    return `${error.name}: ${error.message}`;
  }
  return stringifyUnknown(error) || "Unknown error";
}

// src/platform/core/timestamp-helpers.ts
function padTimestampPart(value) {
  return String(value).padStart(2, "0");
}
function getTimestampParts(now = /* @__PURE__ */ new Date()) {
  return {
    year: now.getFullYear(),
    month: padTimestampPart(now.getMonth() + 1),
    day: padTimestampPart(now.getDate()),
    hour: padTimestampPart(now.getHours()),
    minute: padTimestampPart(now.getMinutes()),
    second: padTimestampPart(now.getSeconds())
  };
}
function getFileTimestamp(now = /* @__PURE__ */ new Date()) {
  const { year, month, day, hour, minute, second } = getTimestampParts(now);
  return `${year}-${month}-${day}_${hour}-${minute}-${second}`;
}
function getHumanReadableNow(now = /* @__PURE__ */ new Date()) {
  const { year, month, day, hour, minute, second } = getTimestampParts(now);
  return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}

// src/platform/core/history-helpers.ts
var DEFAULT_HISTORY_LIMIT = 5;
var DEFAULT_HISTORY_CHAR_LIMIT = 14e3;
var CONVERSATION_HISTORY_SCOPES = [
  "chat",
  "shell-command",
  "commit",
  "review",
  "gen-html",
  "gen-storybook",
  "minify-md",
  "local-server",
  "mcp",
  "security-policy",
  "show-stream",
  "token-optimizer",
  "service-change"
];
var aiServicesRef = [];
function setAiServicesRef(services) {
  aiServicesRef = services;
}
function isConversationHistoryScope(value) {
  return CONVERSATION_HISTORY_SCOPES.includes(value);
}
function parseConversationHistoryEntry(raw) {
  try {
    const parsed = JSON.parse(raw);
    if (!parsed || typeof parsed !== "object") {
      return void 0;
    }
    if (typeof parsed.timestamp !== "string" || typeof parsed.title !== "string" || typeof parsed.summary !== "string" || typeof parsed.scope !== "string" || typeof parsed.service !== "string") {
      return void 0;
    }
    if (!isConversationHistoryScope(parsed.scope) || !aiServicesRef.includes(parsed.service)) {
      return void 0;
    }
    const previousService = typeof parsed.previousService === "string" && (parsed.previousService === "" || aiServicesRef.includes(parsed.previousService)) ? parsed.previousService : void 0;
    const nextService = typeof parsed.nextService === "string" && aiServicesRef.includes(parsed.nextService) ? parsed.nextService : void 0;
    return {
      input: typeof parsed.input === "string" ? parsed.input : void 0,
      nextService,
      output: typeof parsed.output === "string" ? parsed.output : void 0,
      previousService,
      scope: parsed.scope,
      service: parsed.service,
      summary: parsed.summary,
      timestamp: parsed.timestamp,
      title: parsed.title
    };
  } catch {
    return void 0;
  }
}
function appendConversationHistory(paths, entry) {
  const normalizedEntry = {
    ...entry,
    summary: entry.summary.trim() || entry.title.trim(),
    timestamp: entry.timestamp || getHumanReadableNow(),
    title: entry.title.trim()
  };
  fs10__default.default.appendFileSync(paths.conversationHistoryPath, `${JSON.stringify(normalizedEntry)}
`, "utf8");
  return normalizedEntry;
}
function loadConversationHistory(paths, limit = DEFAULT_HISTORY_LIMIT) {
  if (!fs10__default.default.existsSync(paths.conversationHistoryPath)) {
    return [];
  }
  const lines = fs10__default.default.readFileSync(paths.conversationHistoryPath, "utf8").split("\n").map((line) => line.trim()).filter(Boolean);
  if (lines.length === 0) {
    return [];
  }
  return lines.map(parseConversationHistoryEntry).filter((entry) => entry !== void 0).slice(-limit);
}
function formatConversationHistoryEntry(entry, limit) {
  const inputLimit = Math.max(180, Math.floor(limit * 0.35));
  const outputLimit = Math.max(220, limit - inputLimit);
  const lines = [`## ${entry.timestamp} | ${entry.scope} | ${entry.service}`, `\uC81C\uBAA9: ${entry.title}`];
  if (entry.scope === "service-change") {
    lines.push(`\uC11C\uBE44\uC2A4 \uBCC0\uACBD: ${entry.previousService || "(\uC5C6\uC74C)"} -> ${entry.nextService || entry.service}`);
    lines.push(`\uC694\uC57D: ${safeExcerpt(entry.summary, outputLimit)}`);
    return lines.join("\n");
  }
  if (entry.input) {
    lines.push("");
    lines.push("\uC0AC\uC6A9\uC790 \uC785\uB825");
    lines.push(formatCodeBlock(safeExcerpt(entry.input, inputLimit)));
  }
  if (entry.output) {
    lines.push("");
    lines.push("\uC774\uC804 \uACB0\uACFC \uC694\uC57D");
    lines.push(formatCodeBlock(safeExcerpt(entry.output, outputLimit)));
  } else if (entry.summary) {
    lines.push("");
    lines.push("\uACB0\uACFC \uC694\uC57D");
    lines.push(formatCodeBlock(safeExcerpt(entry.summary, outputLimit)));
  }
  return lines.join("\n");
}
function formatConversationHistory(entries, charLimit) {
  if (entries.length === 0) {
    return "";
  }
  const entryLimit = Math.max(400, Math.floor(charLimit / Math.max(entries.length, 1)));
  const content = entries.map((entry) => formatConversationHistoryEntry(entry, entryLimit)).join("\n\n");
  return safeExcerpt(content, charLimit);
}
function loadRecentHistoryContext(paths, limit = DEFAULT_HISTORY_LIMIT, charLimit = DEFAULT_HISTORY_CHAR_LIMIT) {
  const conversationEntries = loadConversationHistory(paths, limit);
  return formatConversationHistory(conversationEntries, charLimit);
}

// src/platform/types/app.ts
var AI_SERVICE = {
  CLAUDE: "claude",
  CODEX: "codex",
  GEMINI: "gemini"
};
function getAvailableFilePath(directory, baseName, extension) {
  const first = path__default.default.join(directory, `${baseName}${extension}`);
  if (!fs10__default.default.existsSync(first)) {
    return first;
  }
  let next = first;
  let count = 1;
  while (fs10__default.default.existsSync(next)) {
    next = path__default.default.join(directory, `${baseName}-${count}${extension}`);
    if (!fs10__default.default.existsSync(next)) {
      break;
    }
    count += 1;
  }
  return next;
}
function appendHistoryIndex(paths, summary, relativeFilePath) {
  const line = `- ${getHumanReadableNow()} | ${summary} | file: \`${relativeFilePath}\`
`;
  fs10__default.default.appendFileSync(paths.historyIndexPath, line, "utf8");
}
function renderSections(sections = []) {
  if (sections.length === 0) {
    return "";
  }
  return sections.map((section) => `
## ${section.heading}

${section.markdown}
`).join("\n");
}
function writeTurnHistory(paths, record) {
  const baseName = `${getFileTimestamp()}-${record.scope}`;
  const filePath = getAvailableFilePath(paths.turnsDir, baseName, ".md");
  const markdown = `# ${record.title}

- \uC2DC\uAC01: ${getHumanReadableNow()}
- scope: \`${record.scope}\`
- service: \`${record.service}\`
- skipped: \`${record.skipped}\`

## \uC0AC\uC6A9\uC790 \uC785\uB825

${formatCodeBlock(record.input)}

## AI \uC751\uB2F5

${record.output || "(\uC751\uB2F5 \uC5C6\uC74C)"}

## \uCD5C\uADFC \uD788\uC2A4\uD1A0\uB9AC \uC8FC\uC785

${formatCodeBlock(record.historyContext)}

## \uC2E4\uD589 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30

${formatCodeBlock(record.previewCommand, "sh")}

## \uC791\uC5C5 \uC804 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4

${formatWorkspaceSnapshot(record.workspaceBefore)}

## \uC791\uC5C5 \uD6C4 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4

${formatWorkspaceSnapshot(record.workspaceAfter)}

## \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uBCC0\uD654

${formatWorkspaceDelta(record.workspaceDelta)}${renderSections(record.extraSections)}
`;
  fs10__default.default.writeFileSync(filePath, markdown, "utf8");
  appendHistoryIndex(paths, `${record.scope} | ${record.service} | ${record.title}`, path__default.default.relative(paths.rootDir, filePath));
  return filePath;
}

// src/platform/core/helpers.ts
var AI_SERVICES = Object.values(AI_SERVICE);
setAiServicesRef(AI_SERVICES);
util.promisify(child_process.execFile);

// src/platform/request-security/registry.ts
var securityRegistryState = globalThis.__JUHONG_E_SECURITY_REGISTRY__ ?? (globalThis.__JUHONG_E_SECURITY_REGISTRY__ = {
  patternRules: /* @__PURE__ */ new Map(),
  validatorRules: /* @__PURE__ */ new Map()
});
var GLOBAL_PATTERN_RULES = securityRegistryState.patternRules;
securityRegistryState.validatorRules;
function addGlobalSecurityPattern(rule) {
  GLOBAL_PATTERN_RULES.set(rule.name, rule);
}

// src/platform/request-security/default-rules.ts
var initialized = false;
function formatResidentRegistrationNumber(matchedText) {
  const digits = matchedText.replace(/\D/g, "");
  if (digits.length !== 13) {
    return `${matchedText.slice(0, 3)}***`;
  }
  return `${digits.slice(0, 6)}-${digits[6]}******`;
}
function ensureDefaultSecurityRules() {
  if (initialized) {
    return;
  }
  initialized = true;
  addGlobalSecurityPattern({
    formatMatch: formatResidentRegistrationNumber,
    message: "\uBCF4\uC548 \uC815\uCC45\uC5D0 \uC758\uD574 \uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638 \uD615\uD0DC\uC758 \uAC12\uC774 \uD3EC\uD568\uB41C \uC785\uB825\uC740 \uC2E4\uD589\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
    name: "resident-registration-number",
    pattern: /\b\d{6}[- ]?[1-4]\d{6}\b/
  });
}
function createPromptHistoryReferences(paths) {
  return {
    aiHistoryDirectoryPath: paths.historyDir,
    promptHistoryFilePath: paths.promptHistoryPath
  };
}
function isPromptMarkdownFileReference(asset) {
  return typeof asset !== "string";
}
function isPromptRuleGroupAsset(asset) {
  return typeof asset !== "string" && !("kind" in asset && asset.kind === "file-reference");
}
function clonePromptMarkdownAsset(asset) {
  return isPromptMarkdownFileReference(asset) ? {
    ...asset,
    filePath: path__default.default.normalize(asset.filePath)
  } : asset;
}
var DEFAULT_STREAM_OUTPUT_STATE = {
  enabled: false
};
globalThis.__JU_HONG_E_STREAM_OUTPUT_STATE__ ?? (globalThis.__JU_HONG_E_STREAM_OUTPUT_STATE__ = {
  ...DEFAULT_STREAM_OUTPUT_STATE
});

// src/platform/actions/shared.ts
function captureActionContext(paths) {
  return {
    historyContext: loadRecentHistoryContext(paths),
    historyReferences: createPromptHistoryReferences(paths),
    workspaceBefore: captureWorkspaceSnapshot(paths.rootDir)
  };
}
function finalizeAction(paths, context, result) {
  const extraSections = [...result.extraSections || [], ...buildPromptAuditSections(result.promptAudit)];
  const workspaceAfter = captureWorkspaceSnapshot(paths.rootDir);
  const workspaceDelta = diffWorkspaceSnapshots(context.workspaceBefore, workspaceAfter);
  const historyPath = writeTurnHistory(paths, {
    extraSections,
    historyContext: context.historyContext,
    input: result.input,
    output: result.output,
    previewCommand: result.previewCommand,
    scope: result.scope,
    service: result.service,
    skipped: result.skipped,
    title: result.title,
    workspaceAfter,
    workspaceBefore: context.workspaceBefore,
    workspaceDelta
  });
  appendConversationHistory(paths, {
    input: result.input,
    output: result.output,
    scope: result.scope,
    service: result.service,
    summary: result.summary,
    title: result.title
  });
  return {
    historyPath,
    previewCommand: result.previewCommand,
    scope: result.scope,
    service: result.service,
    skipped: result.skipped,
    summary: result.summary,
    title: result.title,
    traceMessages: []
  };
}
function formatAuditNumber(value) {
  return value.toLocaleString("ko-KR");
}
function buildPromptAuditSections(promptAudit) {
  if (!promptAudit) {
    return [];
  }
  return [
    {
      heading: "\uD504\uB86C\uD504\uD2B8 \uCD5C\uC801\uD654 \uC694\uC57D",
      markdown: [
        `- mode: \`${promptAudit.mode}\``,
        `- \uCD5C\uC801\uD654 \uC804 \uD504\uB86C\uD504\uD2B8 \uD06C\uAE30: \`${formatAuditNumber(promptAudit.originalBytes)} bytes\``,
        `- \uCD5C\uC801\uD654 \uD6C4 \uD504\uB86C\uD504\uD2B8 \uD06C\uAE30: \`${formatAuditNumber(promptAudit.optimizedBytes)} bytes\``,
        `- \uAC10\uC18C\uD55C \uD504\uB86C\uD504\uD2B8 \uD06C\uAE30: \`${formatAuditNumber(promptAudit.reducedBytes)} bytes\``,
        `- \uAC10\uC18C \uBE44\uC728: \`${promptAudit.reductionPercent}%\``,
        `- \uC608\uC0C1 \uD1A0\uD070(\uC804 -> \uD6C4): \`${formatAuditNumber(promptAudit.originalEstimatedTokens)} -> ${formatAuditNumber(promptAudit.optimizedEstimatedTokens)}\``,
        `- \uAC10\uC18C\uD55C \uC608\uC0C1 \uD1A0\uD070: \`${formatAuditNumber(promptAudit.reducedEstimatedTokens)}\``,
        `- \uC608\uC0C1 \uD1A0\uD070 \uAC10\uC18C \uBE44\uC728: \`${promptAudit.tokenReductionPercent}%\``
      ].join("\n")
    },
    {
      heading: "\uD504\uB86C\uD504\uD2B8 \uCD5C\uC801\uD654 \uC804",
      markdown: formatCodeBlock(promptAudit.originalPrompt)
    },
    {
      heading: "\uD504\uB86C\uD504\uD2B8 \uCD5C\uC801\uD654 \uD6C4",
      markdown: formatCodeBlock(promptAudit.optimizedPrompt)
    }
  ];
}
var ANSI = {
  bold: "\x1B[1m",
  cyan: "\x1B[36m",
  dim: "\x1B[2m",
  gray: "\x1B[90m",
  green: "\x1B[32m",
  red: "\x1B[31m",
  reset: "\x1B[0m",
  yellow: "\x1B[33m"
};
var ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
var COMBINING_MARK_PATTERN = /\p{Mark}/u;
var GRAPHEME_SEGMENTER = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter("ko", { granularity: "grapheme" }) : null;
function colorize(text, color) {
  return `${color}${text}${ANSI.reset}`;
}
function segmentGraphemes(value) {
  if (!GRAPHEME_SEGMENTER) {
    return [...value];
  }
  return [...GRAPHEME_SEGMENTER.segment(value)].map(({ segment }) => segment);
}
function getGraphemeWidth(grapheme) {
  let width = 0;
  for (const character of grapheme) {
    const codePoint = character.codePointAt(0);
    if (!codePoint || COMBINING_MARK_PATTERN.test(character) || codePoint === 8205) {
      continue;
    }
    if (codePoint >= 65024 && codePoint <= 65039 || codePoint >= 917760 && codePoint <= 917999) {
      continue;
    }
    if (isWideCodePoint(codePoint) || isEmojiCodePoint(codePoint)) {
      width = Math.max(width, 2);
      continue;
    }
    width = Math.max(width, 1);
  }
  return width;
}
function tokenizePlainText(value) {
  return segmentGraphemes(value).map((segment) => ({
    value: segment,
    visibleWidth: getGraphemeWidth(segment)
  }));
}
function tokenizeVisibleText(value) {
  const tokens = [];
  let lastIndex = 0;
  for (const match of value.matchAll(ANSI_PATTERN)) {
    const index = match.index ?? 0;
    if (index > lastIndex) {
      tokens.push(...tokenizePlainText(value.slice(lastIndex, index)));
    }
    tokens.push({
      value: match[0],
      visibleWidth: 0
    });
    lastIndex = index + match[0].length;
  }
  if (lastIndex < value.length) {
    tokens.push(...tokenizePlainText(value.slice(lastIndex)));
  }
  return tokens;
}
function isWideCodePoint(codePoint) {
  return codePoint >= 4352 && (codePoint <= 4447 || codePoint === 9001 || codePoint === 9002 || codePoint >= 11904 && codePoint <= 12871 && codePoint !== 12351 || codePoint >= 12880 && codePoint <= 19903 || codePoint >= 19968 && codePoint <= 42182 || codePoint >= 43360 && codePoint <= 43388 || codePoint >= 44032 && codePoint <= 55203 || codePoint >= 63744 && codePoint <= 64255 || codePoint >= 65040 && codePoint <= 65049 || codePoint >= 65072 && codePoint <= 65131 || codePoint >= 65281 && codePoint <= 65376 || codePoint >= 65504 && codePoint <= 65510 || codePoint >= 127488 && codePoint <= 127569 || codePoint >= 131072 && codePoint <= 262141);
}
function isEmojiCodePoint(codePoint) {
  return codePoint >= 127462 && codePoint <= 127487 || codePoint >= 127744 && codePoint <= 129791 || codePoint >= 9728 && codePoint <= 10175;
}
function visibleLength(value) {
  return tokenizeVisibleText(value).reduce((total, token) => total + token.visibleWidth, 0);
}
function sliceVisible(value, width) {
  if (width <= 0) {
    return "";
  }
  let currentWidth = 0;
  let output = "";
  let truncated = false;
  let containsAnsi = false;
  for (const token of tokenizeVisibleText(value)) {
    if (token.visibleWidth === 0) {
      output += token.value;
      containsAnsi = true;
      continue;
    }
    if (currentWidth + token.visibleWidth > width) {
      truncated = true;
      break;
    }
    output += token.value;
    currentWidth += token.visibleWidth;
  }
  if (truncated && containsAnsi && !output.endsWith(ANSI.reset)) {
    output += ANSI.reset;
  }
  return output;
}
function padVisible(value, width) {
  const slicedValue = sliceVisible(value, width);
  const length = visibleLength(slicedValue);
  if (length >= width) {
    return slicedValue;
  }
  return `${slicedValue}${" ".repeat(width - length)}`;
}
function truncateValue(value, width) {
  if (visibleLength(value) <= width) {
    return value;
  }
  if (width <= 3) {
    return sliceVisible(value, width);
  }
  return `${sliceVisible(value, width - 3)}...`;
}
function getViewportWidth() {
  const columns = process$1.stdout.columns || 100;
  return Math.max(Math.min(columns - 2, 108), 4);
}
function getTerminalColumns() {
  return Math.max(process$1.stdout.columns || 100, 4);
}
function createBox(title, lines, footerLines = []) {
  const contentLines = lines.length > 0 ? lines : [""];
  const footer = footerLines.length > 0 ? ["", ...footerLines] : [];
  const width = getViewportWidth();
  const top = `+${"-".repeat(width - 2)}+`;
  const titleLine = `| ${padVisible(colorize(title, ANSI.bold), width - 4)} |`;
  const body = [...contentLines, ...footer].map((line) => `| ${padVisible(line, width - 4)} |`);
  return [top, titleLine, top, ...body, top];
}
function renderScreenBox(title, lines, footerLines = []) {
  console.clear();
  console.log(createBox(title, lines, footerLines).join("\n"));
}
function wrapPlainText(value, firstLineWidth, continuationLineWidth) {
  const renderedLines = [];
  const safeFirstLineWidth = Math.max(firstLineWidth, 1);
  const safeContinuationLineWidth = Math.max(continuationLineWidth, 1);
  const normalizedValue = value.replace(/\r\n?/g, "\n");
  const pushWrappedLine = (line) => {
    if (line.length === 0) {
      renderedLines.push("");
      return;
    }
    let currentLine = "";
    let currentWidth = 0;
    let currentLineWidth = renderedLines.length === 0 ? safeFirstLineWidth : safeContinuationLineWidth;
    for (const segment of segmentGraphemes(line)) {
      const segmentWidth = Math.max(getGraphemeWidth(segment), 1);
      if (currentLine && currentWidth + segmentWidth > currentLineWidth) {
        renderedLines.push(currentLine);
        currentLine = "";
        currentWidth = 0;
        currentLineWidth = safeContinuationLineWidth;
      }
      currentLine += segment;
      currentWidth += segmentWidth;
    }
    renderedLines.push(currentLine);
  };
  normalizedValue.split("\n").forEach(pushWrappedLine);
  return renderedLines.length > 0 ? renderedLines : [""];
}
function buildPromptRenderLayout(promptLabel, buffer, placeholder) {
  const columns = getTerminalColumns();
  const promptLabelWidth = visibleLength(promptLabel);
  const continuationIndentWidth = Math.min(promptLabelWidth, Math.max(columns - 1, 0));
  const continuationIndent = " ".repeat(continuationIndentWidth);
  const firstLineWidth = Math.max(columns - promptLabelWidth, 1);
  const continuationLineWidth = Math.max(columns - continuationIndentWidth, 1);
  const hasBuffer = buffer.length > 0;
  const contentLines = hasBuffer ? wrapPlainText(buffer, firstLineWidth, continuationLineWidth) : wrapPlainText("", firstLineWidth, continuationLineWidth);
  const cursorLines = hasBuffer ? contentLines : [""];
  const renderedPromptLines = contentLines.map((line, index) => {
    const linePrefix = index === 0 ? promptLabel : continuationIndent;
    return `${linePrefix}${hasBuffer ? line : colorize(line, ANSI.dim)}`;
  });
  const activeCursorLine = cursorLines.at(-1) || "";
  const activeCursorLinePrefixWidth = cursorLines.length <= 1 ? promptLabelWidth : continuationIndentWidth;
  return {
    cursorColumn: activeCursorLinePrefixWidth + visibleLength(activeCursorLine),
    cursorRowOffset: Math.max(cursorLines.length - 1, 0),
    lines: renderedPromptLines,
    totalLines: renderedPromptLines.length
  };
}

// src/platform/ui/status.ts
var STATUS_FRAMES = ["-", "\\", "|", "/"];
function formatStatusPrefix(title) {
  return `${colorize(`[${title}]`, `${ANSI.bold}${ANSI.cyan}`)}`;
}
function formatElapsed(startedAt) {
  return `${Math.max(0, Math.floor((Date.now() - startedAt) / 1e3))}s`;
}
function buildStatusRenderLayout(prefix, body) {
  return buildPromptRenderLayout(`${prefix} `, body);
}
function clearRenderedStatus(previousState) {
  if (previousState?.totalLines && previousState.totalLines > 1) {
    readline3__default.default.moveCursor(process$1.stdout, 0, -(previousState.totalLines - 1));
  }
  readline3__default.default.cursorTo(process$1.stdout, 0);
  readline3__default.default.clearScreenDown(process$1.stdout);
}
function renderStatusLayout(layout, previousState) {
  clearRenderedStatus(previousState);
  process$1.stdout.write(layout.lines.join("\n"));
  return {
    totalLines: layout.totalLines
  };
}
function createSessionActionStatus(title) {
  const prefix = formatStatusPrefix(title);
  const print = (message) => {
    console.log(`${prefix} ${message}`);
  };
  return {
    fail(message) {
      print(colorize(message, ANSI.red));
    },
    step(message) {
      print(message);
    },
    async track(message, task) {
      if (!process$1.stdout.isTTY) {
        print(`${message}...`);
        return task();
      }
      const startedAt = Date.now();
      let frameIndex = 0;
      let renderState;
      const render = () => {
        const frame = STATUS_FRAMES[frameIndex % STATUS_FRAMES.length];
        frameIndex += 1;
        renderState = renderStatusLayout(buildStatusRenderLayout(`${prefix} ${frame}`, `${message} (${formatElapsed(startedAt)})`), renderState);
      };
      render();
      const timer = setInterval(render, 120);
      try {
        const result = await task();
        clearInterval(timer);
        renderState = renderStatusLayout(
          buildStatusRenderLayout(`${prefix} done`, `${message} (${formatElapsed(startedAt)})`),
          renderState
        );
        process$1.stdout.write("\n");
        return result;
      } catch (error) {
        clearInterval(timer);
        renderState = renderStatusLayout(
          buildStatusRenderLayout(`${prefix} fail`, `${message} (${formatElapsed(startedAt)})`),
          renderState
        );
        process$1.stdout.write("\n");
        throw error;
      }
    }
  };
}
var telemetryRuntimeState = globalThis.__JU_HONG_E_POSTHOG_RUNTIME_STATE__ ?? (globalThis.__JU_HONG_E_POSTHOG_RUNTIME_STATE__ = {});
function appendSlashCommandTelemetryInputValue(value) {
  if (!telemetryRuntimeState.slashCommandTelemetryInputValues) {
    return;
  }
  telemetryRuntimeState.slashCommandTelemetryInputValues.push(...normalizeSlashCommandTelemetryValues(value));
}
function normalizeSlashCommandTelemetryValues(value) {
  if (value === void 0) {
    return [];
  }
  if (value === null) {
    return [null];
  }
  if (Array.isArray(value)) {
    return value.flatMap((item) => normalizeSlashCommandTelemetryValues(item));
  }
  if (typeof value === "string") {
    return [value];
  }
  if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
    return [String(value)];
  }
  if (typeof value === "object") {
    const objectValue = value;
    if (typeof objectValue.url === "string" && objectValue.url) {
      return [objectValue.url];
    }
    if (typeof objectValue.hash === "string" && objectValue.hash) {
      return [objectValue.hash];
    }
    if (typeof objectValue.name === "string" && objectValue.name) {
      return [objectValue.name];
    }
    if (typeof objectValue.label === "string" && objectValue.label) {
      return [objectValue.label];
    }
    try {
      return [JSON.stringify(objectValue)];
    } catch {
      return ["[object]"];
    }
  }
  return [String(value)];
}
var SINGLE_OPTION_PREFIX_WIDTH = 2;
var SINGLE_OPTION_GAP_WIDTH = 1;
var SINGLE_OPTION_MIN_LABEL_WIDTH = 8;
var SINGLE_OPTION_LABEL_PADDING = 2;
function computeSingleOptionColumnWidths(options) {
  const boxInnerWidth = getViewportWidth() - 4;
  const maxLabelCellWidth = Math.max(
    SINGLE_OPTION_MIN_LABEL_WIDTH,
    ...options.map((option) => visibleLength(option.label) + SINGLE_OPTION_LABEL_PADDING)
  );
  const labelWidth = Math.min(maxLabelCellWidth, Math.floor(boxInnerWidth * 0.5));
  const descriptionWidth = Math.max(0, boxInnerWidth - SINGLE_OPTION_PREFIX_WIDTH - labelWidth - SINGLE_OPTION_GAP_WIDTH);
  return { descriptionWidth, labelWidth };
}
function selectSingleOption(title, options) {
  return new Promise((resolve, reject) => {
    if (options.length === 0) {
      reject(new Error("\uC120\uD0DD \uAC00\uB2A5\uD55C \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."));
      return;
    }
    const { stdin } = process;
    const rawState = "isRaw" in stdin ? Boolean(stdin.isRaw) : false;
    let cursor = 0;
    const cleanup = () => {
      stdin.removeListener("keypress", onKeyPress);
      if (stdin.isTTY) {
        stdin.setRawMode(rawState);
      }
      stdin.pause();
      console.clear();
    };
    const { labelWidth, descriptionWidth } = computeSingleOptionColumnWidths(options);
    const render = () => {
      renderScreenBox(
        title,
        options.map((option, index) => {
          const prefix = cursor === index ? colorize(">", ANSI.green) : " ";
          const label = cursor === index ? colorize(option.label, ANSI.green) : option.label;
          const description = option.description ? truncateValue(option.description, descriptionWidth) : "";
          return `${prefix} ${padVisible(label, labelWidth)} ${colorize(description, ANSI.gray)}`;
        }),
        [
          `${colorize("Up/Down", ANSI.yellow)} \uC774\uB3D9`,
          `${colorize("Enter", ANSI.yellow)} \uC120\uD0DD`,
          `${colorize("ESC", ANSI.yellow)} \uCDE8\uC18C`,
          `${colorize("Ctrl+C", ANSI.yellow)} \uC138\uC158 \uC885\uB8CC`
        ]
      );
    };
    const onKeyPress = (_input, key) => {
      if (key.ctrl && key.name === "c") {
        cleanup();
        reject(createUserTerminatedError("\uC0AC\uC6A9\uC790\uAC00 \uC120\uD0DD \uC785\uB825 \uC911 \uC138\uC158 \uC885\uB8CC\uB97C \uC694\uCCAD\uD588\uC2B5\uB2C8\uB2E4."));
        return;
      }
      if (key.name === "escape") {
        cleanup();
        reject(createUserCancelledError("\uC0AC\uC6A9\uC790\uAC00 \uC120\uD0DD \uC785\uB825\uC744 \uCDE8\uC18C\uD588\uC2B5\uB2C8\uB2E4."));
        return;
      }
      if (key.name === "up") {
        cursor = cursor === 0 ? options.length - 1 : cursor - 1;
        render();
        return;
      }
      if (key.name === "down") {
        cursor = cursor === options.length - 1 ? 0 : cursor + 1;
        render();
        return;
      }
      if (key.name === "return" || key.name === "enter") {
        const selected = options[cursor];
        if (!selected) {
          cleanup();
          reject(new Error("\uC120\uD0DD\uD55C \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
          return;
        }
        cleanup();
        appendSlashCommandTelemetryInputValue(selected.value);
        resolve(selected.value);
      }
    };
    readline3__default.default.emitKeypressEvents(stdin);
    if (stdin.isTTY) {
      stdin.setRawMode(true);
    }
    stdin.resume();
    stdin.on("keypress", onKeyPress);
    render();
  });
}

// src/features/mcp/domain/server-record.ts
var SUPPORTED_HTTP_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
function normalizeMcpServerName(value) {
  const normalized = value.trim();
  if (!normalized) {
    throw new Error("MCP \uC11C\uBC84 \uC774\uB984\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694.");
  }
  if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(normalized)) {
    throw new Error("MCP \uC11C\uBC84 \uC774\uB984\uC740 \uC601\uBB38, \uC22B\uC790, \uC810(.), \uBC11\uC904(_), \uD558\uC774\uD508(-)\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");
  }
  return normalized;
}
function normalizeMcpUrl(value) {
  const normalized = value.trim();
  if (!normalized) {
    throw new Error("MCP \uC11C\uBC84 \uC8FC\uC18C\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.");
  }
  let parsed;
  try {
    parsed = new URL(normalized);
  } catch (error) {
    throw new Error(`\uC720\uD6A8\uD55C MCP \uC11C\uBC84 URL\uC774 \uC544\uB2D9\uB2C8\uB2E4. ${getErrorSummary(error)}`);
  }
  if (!SUPPORTED_HTTP_PROTOCOLS.has(parsed.protocol)) {
    throw new Error(`\uD604\uC7AC\uB294 HTTP/HTTPS MCP \uC11C\uBC84\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. protocol=${parsed.protocol}`);
  }
  return parsed.toString();
}
function normalizeMcpCommand(value) {
  const normalized = value.trim();
  if (!normalized) {
    throw new Error("stdio MCP \uC11C\uBC84 command\uB97C \uC785\uB825\uD574 \uC8FC\uC138\uC694.");
  }
  return normalized;
}
function normalizeMcpArgs(values = []) {
  return values.map((value) => value.trim()).filter(Boolean);
}
function createMcpServerRecord(input, timestamps) {
  const name = normalizeMcpServerName(input.name);
  if (input.transport === "http") {
    return {
      createdAt: timestamps.createdAt,
      name,
      transport: "http",
      updatedAt: timestamps.updatedAt,
      url: normalizeMcpUrl(input.url)
    };
  }
  return {
    args: normalizeMcpArgs(input.args),
    command: normalizeMcpCommand(input.command),
    createdAt: timestamps.createdAt,
    name,
    transport: "stdio",
    updatedAt: timestamps.updatedAt
  };
}
function parsePersistedMcpServerRecord(value) {
  if (!value || typeof value !== "object") {
    return void 0;
  }
  const raw = value;
  if (typeof raw.name !== "string" || typeof raw.createdAt !== "string" || typeof raw.updatedAt !== "string") {
    return void 0;
  }
  if ((raw.transport === "http" || typeof raw.url === "string") && typeof raw.url === "string") {
    return createMcpServerRecord(
      {
        name: raw.name,
        transport: "http",
        url: raw.url
      },
      {
        createdAt: raw.createdAt,
        updatedAt: raw.updatedAt
      }
    );
  }
  if (raw.transport === "stdio" && typeof raw.command === "string") {
    return createMcpServerRecord(
      {
        args: Array.isArray(raw.args) ? raw.args.filter((entry) => typeof entry === "string") : [],
        command: raw.command,
        name: raw.name,
        transport: "stdio"
      },
      {
        createdAt: raw.createdAt,
        updatedAt: raw.updatedAt
      }
    );
  }
  return void 0;
}
function isHttpMcpServer(server) {
  return server.transport === "http";
}
function describeMcpServerRecord(server) {
  return isHttpMcpServer(server) ? server.url : [server.command, ...server.args].join(" ");
}
function getMcpServerTransportLabel(server) {
  return server.transport;
}
function getMcpServerTargetLabel(server) {
  return isHttpMcpServer(server) ? "url" : "command";
}
var MCP_REGISTRY_VERSION = 1;
var MCP_SERVICE_ORDER = ["codex", "gemini", "claude"];
var MCP_UNREGISTER_BY_SERVICE = {
  claude: removeClaudeServer,
  codex: removeCodexServer,
  gemini: removeGeminiServer
};
function getMcpPaths(paths) {
  return {
    directoryPath: paths.mcpDir,
    registryPath: paths.mcpRegistryPath
  };
}
function loadMcpRegistry(paths) {
  const mcpPaths = getMcpPaths(paths);
  if (!fs10__default.default.existsSync(mcpPaths.registryPath)) {
    return {
      servers: [],
      version: MCP_REGISTRY_VERSION
    };
  }
  try {
    const parsed = JSON.parse(fs10__default.default.readFileSync(mcpPaths.registryPath, "utf8"));
    const servers = Array.isArray(parsed.servers) ? parsed.servers.map((server) => parsePersistedMcpServerRecord(server)).filter((server) => Boolean(server)).filter((server) => server.name) : [];
    return {
      servers: servers.sort((left, right) => left.name.localeCompare(right.name)),
      version: typeof parsed.version === "number" ? parsed.version : MCP_REGISTRY_VERSION
    };
  } catch {
    return {
      servers: [],
      version: MCP_REGISTRY_VERSION
    };
  }
}
function saveMcpRegistry(paths, registry) {
  const mcpPaths = getMcpPaths(paths);
  fs10__default.default.mkdirSync(mcpPaths.directoryPath, { recursive: true });
  fs10__default.default.writeFileSync(
    mcpPaths.registryPath,
    `${JSON.stringify(
      {
        servers: [...registry.servers].sort((left, right) => left.name.localeCompare(right.name)),
        version: MCP_REGISTRY_VERSION
      },
      null,
      2
    )}
`,
    "utf8"
  );
}
function stripJsonComments(value) {
  let result = "";
  let inString = false;
  let inLineComment = false;
  let inBlockComment = false;
  let quote = "";
  for (let index = 0; index < value.length; index += 1) {
    const character = value[index] || "";
    const nextCharacter = value[index + 1] || "";
    const previousCharacter = value[index - 1] || "";
    if (inLineComment) {
      if (character === "\n") {
        inLineComment = false;
        result += character;
      }
      continue;
    }
    if (inBlockComment) {
      if (character === "*" && nextCharacter === "/") {
        inBlockComment = false;
        index += 1;
      }
      continue;
    }
    if (inString) {
      result += character;
      if (character === quote && previousCharacter !== "\\") {
        inString = false;
        quote = "";
      }
      continue;
    }
    if ((character === '"' || character === "'") && previousCharacter !== "\\") {
      inString = true;
      quote = character;
      result += character;
      continue;
    }
    if (character === "/" && nextCharacter === "/") {
      inLineComment = true;
      index += 1;
      continue;
    }
    if (character === "/" && nextCharacter === "*") {
      inBlockComment = true;
      index += 1;
      continue;
    }
    result += character;
  }
  return result;
}
function readGeminiSettingsFile() {
  const settingsPath = path__default.default.join(os3__default.default.homedir(), ".gemini", "settings.json");
  if (!fs10__default.default.existsSync(settingsPath)) {
    return {
      settings: {},
      settingsPath
    };
  }
  try {
    const parsed = JSON.parse(stripJsonComments(fs10__default.default.readFileSync(settingsPath, "utf8").trim() || "{}"));
    return {
      settings: parsed,
      settingsPath
    };
  } catch {
    return {
      settings: {},
      settingsPath
    };
  }
}
function writeGeminiSettingsFile(settings) {
  const { settingsPath } = readGeminiSettingsFile();
  fs10__default.default.mkdirSync(path__default.default.dirname(settingsPath), { recursive: true });
  fs10__default.default.writeFileSync(settingsPath, `${JSON.stringify(settings, null, 2)}
`, "utf8");
  return settingsPath;
}
function runCliCommand(command, args) {
  const result = child_process.spawnSync(command, args, {
    encoding: "utf8",
    maxBuffer: 1024 * 1024 * 10
  });
  return {
    detail: [result.stdout, result.stderr].map((value) => value?.trim()).filter(Boolean).join("\n"),
    ok: !result.error && result.status === 0,
    result
  };
}
function isServiceCliAvailable(service) {
  const binaryName = service === "codex" ? "codex" : service === "gemini" ? "gemini" : "claude";
  const result = child_process.spawnSync(binaryName, ["--version"], {
    encoding: "utf8",
    maxBuffer: 1024 * 1024 * 2
  });
  return !result.error && result.status === 0;
}
function removeCodexServer(server, parsedArgs, trace) {
  if (parsedArgs.testMode) {
    return {
      detail: `\uD14C\uC2A4\uD2B8 \uBAA8\uB4DC\uB77C codex mcp remove ${server.name} \uC2E4\uD589\uC744 \uC0DD\uB7B5\uD588\uC2B5\uB2C8\uB2E4.`,
      ok: true,
      service: "codex",
      skipped: true
    };
  }
  if (!isServiceCliAvailable("codex")) {
    return {
      detail: "codex CLI\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
      ok: false,
      service: "codex"
    };
  }
  trace("mcp:codex:remove:start", server.name);
  const removeResult = runCliCommand("codex", ["mcp", "remove", server.name]);
  const verifyResult = runCliCommand("codex", ["mcp", "get", server.name]);
  const ok = !verifyResult.ok;
  trace("mcp:codex:remove:end", `${server.name} | ${ok}`);
  return {
    detail: ok ? `\uC0AD\uC81C \uC644\uB8CC: ${server.name}` : removeResult.detail || verifyResult.detail || "\uC0AD\uC81C \uD6C4 \uAC80\uC99D\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
    ok,
    service: "codex"
  };
}
function removeClaudeServer(server, parsedArgs, trace) {
  if (parsedArgs.testMode) {
    return {
      detail: `\uD14C\uC2A4\uD2B8 \uBAA8\uB4DC\uB77C claude mcp remove --scope user ${server.name} \uC2E4\uD589\uC744 \uC0DD\uB7B5\uD588\uC2B5\uB2C8\uB2E4.`,
      ok: true,
      service: "claude",
      skipped: true
    };
  }
  if (!isServiceCliAvailable("claude")) {
    return {
      detail: "claude CLI\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.",
      ok: false,
      service: "claude"
    };
  }
  trace("mcp:claude:remove:start", server.name);
  const removeResult = runCliCommand("claude", ["mcp", "remove", "--scope", "user", server.name]);
  const verifyResult = runCliCommand("claude", ["mcp", "get", server.name]);
  const ok = !verifyResult.ok;
  trace("mcp:claude:remove:end", `${server.name} | ${ok}`);
  return {
    detail: ok ? `\uC0AD\uC81C \uC644\uB8CC: ${server.name}` : removeResult.detail || verifyResult.detail || "\uC0AD\uC81C \uD6C4 \uAC80\uC99D\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
    ok,
    service: "claude"
  };
}
function removeGeminiServer(server, parsedArgs, trace) {
  if (parsedArgs.testMode) {
    return {
      detail: `\uD14C\uC2A4\uD2B8 \uBAA8\uB4DC\uB77C ~/.gemini/settings.json \uC758 mcpServers.${server.name} \uC81C\uAC70\uB97C \uC0DD\uB7B5\uD588\uC2B5\uB2C8\uB2E4.`,
      ok: true,
      service: "gemini",
      skipped: true
    };
  }
  trace("mcp:gemini:remove:start", server.name);
  const { settings } = readGeminiSettingsFile();
  const nextServers = { ...settings.mcpServers || {} };
  delete nextServers[server.name];
  const nextSettings = { ...settings };
  if (Object.keys(nextServers).length > 0) {
    nextSettings.mcpServers = nextServers;
  } else {
    delete nextSettings.mcpServers;
  }
  const settingsPath = writeGeminiSettingsFile(nextSettings);
  const ok = !readGeminiSettingsFile().settings.mcpServers?.[server.name];
  trace("mcp:gemini:remove:end", `${server.name} | ${ok}`);
  return {
    detail: ok ? `\uC0AD\uC81C \uC644\uB8CC: ${settingsPath}` : "settings.json \uC0AD\uC81C \uD6C4 \uAC80\uC99D\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.",
    ok,
    service: "gemini"
  };
}
function unregisterMcpServerForService(server, service, parsedArgs, trace) {
  return MCP_UNREGISTER_BY_SERVICE[service](server, parsedArgs, trace);
}
function unregisterMcpServerForAllServices(server, parsedArgs, trace) {
  return MCP_SERVICE_ORDER.map((service) => unregisterMcpServerForService(server, service, parsedArgs, trace));
}
function listRegisteredMcpServers(paths) {
  return loadMcpRegistry(paths).servers;
}
function removeRegisteredMcpServer(paths, serverName) {
  const registry = loadMcpRegistry(paths);
  const targetIndex = registry.servers.findIndex((server) => server.name === serverName);
  if (targetIndex < 0) {
    return void 0;
  }
  const [removed] = registry.servers.splice(targetIndex, 1);
  saveMcpRegistry(paths, registry);
  return removed;
}

// src/features/mcp/application/action.ts
function createMcpSelectOptions(servers) {
  return servers.map((server) => ({
    description: describeMcpServerRecord(server),
    label: server.name,
    value: server
  }));
}
function sortServiceResults(serviceResults) {
  return [...serviceResults].sort(
    (left, right) => MCP_SERVICE_ORDER.indexOf(left.service) - MCP_SERVICE_ORDER.indexOf(right.service)
  );
}
function formatServiceResults(serviceResults) {
  return sortServiceResults(serviceResults).map((result) => {
    const status = result.ok ? "\uC131\uACF5" : "\uC2E4\uD328";
    const suffix = result.skipped ? " (\uC0DD\uB7B5)" : "";
    return `- ${result.service}: \`${status}${suffix}\` - ${result.detail}`;
  }).join("\n");
}
async function chooseRegisteredMcpServer(paths, title) {
  const servers = listRegisteredMcpServers(paths);
  if (servers.length === 0) {
    return void 0;
  }
  return selectSingleOption(title, createMcpSelectOptions(servers));
}
async function runMcpUnregisterAction(options) {
  let stage = "select-server";
  options.trace("mcp:unregister:start", `service=${options.service}`);
  try {
    const status = createSessionActionStatus("mcp");
    status.step("1/5 \uB4F1\uB85D \uD574\uC81C\uD560 MCP \uC11C\uBC84\uB97C \uC120\uD0DD\uD558\uB294 \uC911\uC785\uB2C8\uB2E4.");
    const context = captureActionContext(options.paths);
    const selectedServer = await chooseRegisteredMcpServer(options.paths, "\uB4F1\uB85D \uD574\uC81C\uD560 MCP \uC11C\uBC84\uB97C \uC120\uD0DD\uD558\uC138\uC694.");
    if (!selectedServer) {
      options.trace("mcp:unregister:skipped", "no-registered-server");
      const output2 = "\uB4F1\uB85D\uB41C MCP \uC11C\uBC84\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.";
      console.log(output2);
      const record2 = finalizeAction(options.paths, context, {
        input: "/mcp-unregister",
        output: output2,
        previewCommand: "",
        scope: "mcp",
        service: options.service,
        skipped: options.parsedArgs.testMode,
        summary: "MCP \uC11C\uBC84 \uB4F1\uB85D \uD574\uC81C: \uB300\uC0C1 \uC5C6\uC74C",
        title: "MCP \uC11C\uBC84 \uB4F1\uB85D \uD574\uC81C"
      });
      options.trace("mcp:unregister:end", `history=${record2.historyPath || "(\uC5C6\uC74C)"} skipped=no-target`);
      return record2;
    }
    options.trace("mcp:unregister:selected", selectedServer.name);
    status.step("2/5 \uC11C\uBE44\uC2A4\uBCC4 MCP \uC124\uC815 \uC81C\uAC70\uB97C \uC9C4\uD589\uD558\uB294 \uC911\uC785\uB2C8\uB2E4.");
    stage = "sync-services";
    const serviceResults = await status.track(
      "3/5 \uC11C\uBE44\uC2A4\uBCC4 MCP \uC124\uC815\uC744 \uC81C\uAC70\uD558\uB294 \uC911\uC785\uB2C8\uB2E4",
      async () => unregisterMcpServerForAllServices(selectedServer, options.parsedArgs, options.trace)
    );
    options.trace(
      "mcp:unregister:services",
      `ok=${serviceResults.filter((result) => result.ok).length} failed=${serviceResults.filter((result) => !result.ok).length}`
    );
    if (serviceResults.some((result) => !result.ok)) {
      throw new Error(`\uC77C\uBD80 \uC11C\uBE44\uC2A4\uC5D0\uC11C MCP \uC11C\uBC84 \uB4F1\uB85D \uD574\uC81C\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
${formatServiceResults(serviceResults)}`);
    }
    stage = "remove-registry";
    removeRegisteredMcpServer(options.paths, selectedServer.name);
    const output = [
      "MCP \uC11C\uBC84 \uB4F1\uB85D\uC744 \uD574\uC81C\uD588\uC2B5\uB2C8\uB2E4.",
      `name: ${selectedServer.name}`,
      `transport: ${getMcpServerTransportLabel(selectedServer)}`,
      `${getMcpServerTargetLabel(selectedServer)}: ${describeMcpServerRecord(selectedServer)}`,
      "",
      "\uC11C\uBE44\uC2A4\uBCC4 \uC81C\uAC70 \uACB0\uACFC",
      ...sortServiceResults(serviceResults).map((result) => `- ${result.service}: ${result.ok ? "\uC131\uACF5" : "\uC2E4\uD328"} - ${result.detail}`)
    ].join("\n");
    status.step("4/5 \uB4F1\uB85D \uD574\uC81C \uACB0\uACFC\uB97C \uC815\uB9AC\uD558\uB294 \uC911\uC785\uB2C8\uB2E4.");
    status.step("5/5 \uC791\uC5C5 \uC774\uB825\uC744 \uC800\uC7A5\uD558\uB294 \uC911\uC785\uB2C8\uB2E4.");
    console.log(output);
    stage = "finalize-record";
    const record = finalizeAction(options.paths, context, {
      extraSections: [
        {
          heading: "\uD574\uC81C\uD55C MCP \uC11C\uBC84",
          markdown: [
            `- name: \`${selectedServer.name}\``,
            `- transport: \`${getMcpServerTransportLabel(selectedServer)}\``,
            `- ${getMcpServerTargetLabel(selectedServer)}: \`${describeMcpServerRecord(selectedServer)}\``
          ].join("\n")
        },
        {
          heading: "\uC11C\uBE44\uC2A4\uBCC4 \uC81C\uAC70 \uACB0\uACFC",
          markdown: formatServiceResults(serviceResults)
        }
      ],
      input: `/mcp-unregister
name=${selectedServer.name}`,
      output,
      previewCommand: "",
      scope: "mcp",
      service: options.service,
      skipped: options.parsedArgs.testMode,
      summary: `MCP \uC11C\uBC84 \uB4F1\uB85D \uD574\uC81C: ${selectedServer.name}`,
      title: "MCP \uC11C\uBC84 \uB4F1\uB85D \uD574\uC81C"
    });
    options.trace("mcp:unregister:end", `history=${record.historyPath || "(\uC5C6\uC74C)"} name=${selectedServer.name}`);
    return record;
  } catch (error) {
    if (isUserTerminatedError(error)) {
      options.trace("mcp:unregister:terminated", stage);
    } else if (isUserCancelledError(error)) {
      options.trace("mcp:unregister:cancelled", stage);
    } else {
      options.trace("mcp:unregister:error", `${stage} ${getErrorSummary(error)}`);
    }
    throw error;
  }
}

// src/platform/runtime-profile.ts
globalThis.__JU_HONG_E_RUNTIME_PROFILE__ ?? (globalThis.__JU_HONG_E_RUNTIME_PROFILE__ = {
  binaryName: "ju-hong-e",
  profile: "all"
});

// src/platform/command-runtime/registry.ts
var registryState = globalThis.__JU_HONG_E_COMMAND_REGISTRY__ ?? (globalThis.__JU_HONG_E_COMMAND_REGISTRY__ = {
  juHongECommands: /* @__PURE__ */ new Map()
});
var JU_HONG_E_COMMANDS = registryState.juHongECommands;
function resolveRegistration(registration, api) {
  if (typeof registration === "function") {
    return registration(api);
  }
  return registration;
}
function createCommand(definition) {
  return {
    ...definition,
    forms: definition.forms ? definition.forms.map(clonePromptMarkdownAsset) : void 0,
    instructions: definition.instructions ? definition.instructions.map(clonePromptMarkdownAsset) : void 0,
    kind: "ju-hong-e",
    rules: definition.rules ? definition.rules.map(
      (ruleAsset) => !isPromptRuleGroupAsset(ruleAsset) ? clonePromptMarkdownAsset(ruleAsset) : {
        ...ruleAsset,
        fileNamePatterns: ruleAsset.fileNamePatterns ? [...ruleAsset.fileNamePatterns] : void 0,
        rules: ruleAsset.rules ? ruleAsset.rules.map(clonePromptMarkdownAsset) : void 0
      }
    ) : void 0
  };
}
var REGISTRATION_API = {
  createCommand
};
function addCommand(registration) {
  ensureDefaultSecurityRules();
  const definition = resolveRegistration(registration, REGISTRATION_API);
  if (JU_HONG_E_COMMANDS.has(definition.command)) {
    throw new Error(`\uC774\uBBF8 \uB4F1\uB85D\uB41C \uC8FC\uD64D\uC774 \uBA85\uB839\uC5B4\uC785\uB2C8\uB2E4. command=${definition.command}`);
  }
  JU_HONG_E_COMMANDS.set(definition.command, definition);
}

// src/command-modules/mcp-unregister/index.ts
addCommand(
  ({ createCommand: createCommand2 }) => createCommand2({
    command: "/mcp-unregister",
    description: "\uB4F1\uB85D\uB41C MCP \uC11C\uBC84 \uC81C\uAC70",
    /**
     * @description
     * `execute` 는 대상 값를 실행한다.
     * 사용자가 해당 builtin 명령을 선택했을 때 가장 먼저 호출되는 실행 엔트리다.
     *
     * @param context 현재 명령 또는 action 실행 컨텍스트
     * @returns execute 비동기 처리 결과
     */
    execute: async (context) => {
      const record = await runMcpUnregisterAction({
        parsedArgs: context.parsedArgs,
        paths: context.paths,
        service: context.service,
        trace: context.trace
      });
      return {
        record
      };
    },
    order: 43
  })
);
