import os, { networkInterfaces, userInfo, hostname } from 'node:os';
import { PostHog } from 'posthog-node';
import { execFile, execSync } from 'node:child_process';
import { promisify, inspect } from 'node:util';
import fs from 'node:fs';
import path3 from 'node:path';
import fs2 from 'node:fs/promises';
import { fileURLToPath } from 'node:url';

// src/platform/analytics/posthog.ts
function runGitCommand(rootDir, command) {
  return 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 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 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}`;
}
function getAvailableFilePath(directory, baseName, extension) {
  const first = path3.join(directory, `${baseName}${extension}`);
  if (!fs.existsSync(first)) {
    return first;
  }
  let next = first;
  let count = 1;
  while (fs.existsSync(next)) {
    next = path3.join(directory, `${baseName}-${count}${extension}`);
    if (!fs.existsSync(next)) {
      break;
    }
    count += 1;
  }
  return next;
}
function renderSections(sections = []) {
  if (sections.length === 0) {
    return "";
  }
  return sections.map((section) => `
## ${section.heading}

${section.markdown}
`).join("\n");
}
function serializeError(error) {
  const serialized = {
    summary: getErrorSummary(error)
  };
  if (error instanceof Error) {
    serialized.name = error.name;
    serialized.message = error.message;
    serialized.stack = error.stack;
  } else {
    serialized.value = stringifyUnknown(error);
  }
  if (error && typeof error === "object") {
    const errorLike = error;
    ["code", "errno", "syscall", "path", "cmd", "status", "signal"].forEach((key) => {
      if (errorLike[key] !== void 0) {
        serialized[key] = errorLike[key];
      }
    });
    const stdout = stringifyUnknown(errorLike.stdout);
    if (stdout) {
      serialized.stdout = stdout;
    }
    const stderr = stringifyUnknown(errorLike.stderr);
    if (stderr) {
      serialized.stderr = stderr;
    }
  }
  return serialized;
}
function writeErrorReport(paths, error, options) {
  const filePath = getAvailableFilePath(paths.errorDir, `${getFileTimestamp()}-error`, ".md");
  const serializedError = serializeError(error);
  const traceMessages = options.traceMessages ?? [];
  const markdown = `# Error Report

- \uC2DC\uAC01: ${getHumanReadableNow()}
- scope: \`${options.scope}\`
- \uC791\uC5C5 \uACBD\uB85C: \`${paths.rootDir}\`
- \uC2E4\uD589 \uC778\uC790: \`${JSON.stringify(options.args ?? process.argv.slice(2))}\`

## Summary

${serializedError.summary || "Unknown error"}

## Error

\`\`\`json
${JSON.stringify(serializedError, null, 2)}
\`\`\`

## Trace

\`\`\`json
${JSON.stringify(traceMessages, null, 2)}
\`\`\`${renderSections(options.extraSections)}
`;
  fs.writeFileSync(filePath, markdown, "utf8");
  return filePath;
}

// src/platform/analytics/posthog.ts
var POSTHOG_API_KEY = "phc_MX929Nca94SLcOo7b5Mdvhv9KQi7lSESFNKRhAJRKi9";
var POSTHOG_HOST = "https://us.i.posthog.com";
var telemetryRuntimeState = globalThis.__JU_HONG_E_POSTHOG_RUNTIME_STATE__ ?? (globalThis.__JU_HONG_E_POSTHOG_RUNTIME_STATE__ = {});
function getPostHogClient() {
  if (!telemetryRuntimeState.posthogClient) {
    telemetryRuntimeState.posthogClient = new PostHog(POSTHOG_API_KEY, {
      host: POSTHOG_HOST
    });
  }
  return telemetryRuntimeState.posthogClient;
}
function readGitConfigValue(rootDir, configKey) {
  if (!isGitRepository(rootDir)) {
    return null;
  }
  try {
    return runGitCommand(rootDir, `git config --get ${configKey}`) || null;
  } catch {
    return null;
  }
}
function resolveDistinctId(gitUserName, gitUserEmail) {
  if (gitUserEmail) {
    return `git-email:${gitUserEmail}`;
  }
  if (gitUserName) {
    return `git-name:${gitUserName}`;
  }
  try {
    const currentUser = userInfo();
    return `os-user:${currentUser.username}@${hostname()}`;
  } catch {
    return `host:${hostname()}`;
  }
}
function resolveGitTelemetryMetadata(rootDir) {
  const gitUserName = readGitConfigValue(rootDir, "user.name");
  const gitUserEmail = readGitConfigValue(rootDir, "user.email");
  return {
    distinctId: resolveDistinctId(gitUserName, gitUserEmail),
    gitUserEmail,
    gitUserName
  };
}
function resolveUserIpAddressValue() {
  const ipAddresses = /* @__PURE__ */ new Set();
  Object.values(networkInterfaces()).forEach((records) => {
    records?.forEach((record) => {
      if (!record || record.internal) {
        return;
      }
      ipAddresses.add(record.address);
    });
  });
  return [...ipAddresses].join(", ");
}
function buildCommandParameterProperties(args) {
  const parameterProperties = {};
  if (args.length === 0) {
    parameterProperties["\uBA85\uB839\uC5B4\uC5D0\uC0AC\uC6A9\uB41C\uD30C\uB77C\uBBF8\uD1301"] = null;
    return parameterProperties;
  }
  args.forEach((arg, index) => {
    parameterProperties[`\uBA85\uB839\uC5B4\uC5D0\uC0AC\uC6A9\uB41C\uD30C\uB77C\uBBF8\uD130${index + 1}`] = arg;
  });
  return parameterProperties;
}
function beginSlashCommandTelemetryInputCollection(initialArgs) {
  telemetryRuntimeState.slashCommandTelemetryInputValues = [...initialArgs];
}
function endSlashCommandTelemetryInputCollection() {
  const values = [...telemetryRuntimeState.slashCommandTelemetryInputValues || []];
  telemetryRuntimeState.slashCommandTelemetryInputValues = void 0;
  return values;
}
function trackSlashCommandExecution(options) {
  try {
    const gitMetadata = resolveGitTelemetryMetadata(options.rootDir);
    getPostHogClient().capture({
      distinctId: gitMetadata.distinctId,
      event: options.command,
      properties: {
        "userinfo-git-user-email": gitMetadata.gitUserEmail,
        "userinfo-git-user-name": gitMetadata.gitUserName,
        "userinfo-ip": resolveUserIpAddressValue(),
        "command-kind": options.kind,
        "command-service": options.service,
        "command-status": options.status,
        ...buildCommandParameterProperties(options.args)
      }
    });
    options.trace?.("posthog:slash-command:capture", `${options.command} status=${options.status}`);
  } catch (error) {
    options.trace?.("posthog:slash-command:skip", getErrorSummary(error));
  }
}

// src/platform/core/cancellation.ts
var USER_CANCELLED_ERROR_CODE = "JUHONG_E_USER_CANCELLED";
var USER_TERMINATED_ERROR_CODE = "JUHONG_E_USER_TERMINATED";
function hasCancellationErrorCode(error, code) {
  return Boolean(
    error && typeof error === "object" && "code" in error && error.code === code
  );
}
function isUserCancelledError(error) {
  return hasCancellationErrorCode(error, USER_CANCELLED_ERROR_CODE);
}
function isUserTerminatedError(error) {
  return hasCancellationErrorCode(error, USER_TERMINATED_ERROR_CODE);
}
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: path3.normalize(asset.filePath)
  } : asset;
}
var execFileAsync = promisify(execFile);
var MAX_REFERENCED_RESOURCES = 16;
var MAX_TEXT_LENGTH = 12e4;
var MAX_FILE_BUFFER = 1024 * 1024 * 4;
var MAX_REMOTE_BUFFER = 1024 * 1024 * 5;
var COMMAND_TIMEOUT_MS = 15e3;
var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
  ".cjs",
  ".conf",
  ".css",
  ".csv",
  ".d.ts",
  ".env",
  ".html",
  ".htm",
  ".ini",
  ".java",
  ".js",
  ".json",
  ".jsx",
  ".kt",
  ".less",
  ".log",
  ".md",
  ".mjs",
  ".php",
  ".py",
  ".rb",
  ".rs",
  ".scss",
  ".sh",
  ".sql",
  ".svg",
  ".swift",
  ".ts",
  ".tsx",
  ".txt",
  ".xml",
  ".yaml",
  ".yml",
  ".zsh"
]);
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".bmp", ".gif", ".heic", ".jpeg", ".jpg", ".png", ".tif", ".tiff", ".webp"]);
var TEXTUTIL_EXTENSIONS = /* @__PURE__ */ new Set([".doc", ".docx", ".odt", ".rtf", ".rtfd", ".webarchive"]);
var REMOTE_URL_PATTERN = /\bhttps?:\/\/[^\s<>()"'`]+/gi;
var FILE_URL_PATTERN = /\bfile:\/\/[^\s<>()"'`]+/gi;
var LOCAL_PATH_WITH_PREFIX_PATTERN = /(?:^|[\s("'`])((?:~|\.{1,2}\/|\/)[^\s<>()"'`]+)/g;
var RELATIVE_PATH_WITH_SEPARATOR_PATTERN = /(?:^|[\s("'`])((?:[A-Za-z0-9._-]+\/)+[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+)/g;
function trimTrailingPunctuation(value) {
  return value.replace(/[),.;:!?`'"\]}]+$/g, "").trim();
}
function limitTextContent(value) {
  if (!value) {
    return "";
  }
  const normalized = value.replace(/\0/g, "").trim();
  if (normalized.length <= MAX_TEXT_LENGTH) {
    return normalized;
  }
  return normalized.slice(0, MAX_TEXT_LENGTH);
}
function isLikelyTextMimeType(mimeType) {
  return mimeType.startsWith("text/") || mimeType.includes("json") || mimeType.includes("javascript") || mimeType.includes("xml") || mimeType.includes("yaml") || mimeType.includes("svg");
}
function isLikelyImageMimeType(mimeType) {
  return mimeType.startsWith("image/");
}
function collectMatches(text, pattern) {
  const values = [];
  for (const match of text.matchAll(pattern)) {
    const candidate = trimTrailingPunctuation((match[1] || match[0] || "").trim());
    if (!candidate) {
      continue;
    }
    values.push(candidate);
  }
  return values;
}
function resolveLocalResource(value, rootDir) {
  try {
    if (value.startsWith("file://")) {
      return path3.normalize(fileURLToPath(value));
    }
  } catch {
    return void 0;
  }
  if (value.startsWith("~")) {
    return path3.normalize(path3.join(os.homedir(), value.slice(1)));
  }
  if (path3.isAbsolute(value)) {
    return path3.normalize(value);
  }
  if (!rootDir) {
    return void 0;
  }
  return path3.normalize(path3.resolve(rootDir, value));
}
function toReferencedResources(values, rootDir) {
  const seen = /* @__PURE__ */ new Set();
  const resources = [];
  for (const value of values) {
    for (const candidate of collectMatches(value, REMOTE_URL_PATTERN)) {
      const normalized = trimTrailingPunctuation(candidate);
      if (!normalized || seen.has(normalized)) {
        continue;
      }
      seen.add(normalized);
      resources.push({
        kind: "remote-url",
        location: normalized
      });
    }
    for (const candidate of [...collectMatches(value, FILE_URL_PATTERN), ...collectMatches(value, LOCAL_PATH_WITH_PREFIX_PATTERN), ...collectMatches(value, RELATIVE_PATH_WITH_SEPARATOR_PATTERN)]) {
      const resolved = resolveLocalResource(candidate, rootDir);
      if (!resolved || seen.has(resolved)) {
        continue;
      }
      seen.add(resolved);
      resources.push({
        kind: "local-file",
        location: resolved
      });
    }
    if (resources.length >= MAX_REFERENCED_RESOURCES) {
      return resources.slice(0, MAX_REFERENCED_RESOURCES);
    }
  }
  return resources;
}
async function detectLocalMimeType(filePath) {
  try {
    const { stdout } = await execFileAsync("file", ["--brief", "--mime-type", filePath], {
      maxBuffer: 64 * 1024,
      timeout: COMMAND_TIMEOUT_MS
    });
    return stdout.trim().toLowerCase();
  } catch {
    return "";
  }
}
async function readTextFile(filePath) {
  try {
    const stat = await fs2.stat(filePath);
    if (stat.size > MAX_FILE_BUFFER) {
      const handle = await fs2.open(filePath, "r");
      try {
        const buffer2 = Buffer.alloc(MAX_FILE_BUFFER);
        await handle.read(buffer2, 0, MAX_FILE_BUFFER, 0);
        return limitTextContent(buffer2.toString("utf8"));
      } finally {
        await handle.close();
      }
    }
    const buffer = await fs2.readFile(filePath);
    return limitTextContent(buffer.toString("utf8"));
  } catch {
    return "";
  }
}
async function readTextViaTextutil(filePath) {
  try {
    const { stdout } = await execFileAsync("textutil", ["-convert", "txt", "-stdout", filePath], {
      maxBuffer: MAX_FILE_BUFFER,
      timeout: COMMAND_TIMEOUT_MS
    });
    return limitTextContent(stdout);
  } catch {
    return "";
  }
}
async function readTextViaMetadata(filePath) {
  try {
    const { stdout } = await execFileAsync("mdls", ["-raw", "-name", "kMDItemTextContent", filePath], {
      maxBuffer: MAX_FILE_BUFFER,
      timeout: COMMAND_TIMEOUT_MS
    });
    const normalized = stdout.trim();
    if (!normalized || normalized === "(null)") {
      return "";
    }
    return limitTextContent(normalized);
  } catch {
    return "";
  }
}
async function readTextViaStrings(filePath) {
  try {
    const { stdout } = await execFileAsync("strings", ["-n", "6", filePath], {
      maxBuffer: MAX_FILE_BUFFER,
      timeout: COMMAND_TIMEOUT_MS
    });
    return limitTextContent(stdout);
  } catch {
    return "";
  }
}
async function readTextViaTesseract(filePath) {
  try {
    const { stdout } = await execFileAsync("tesseract", [filePath, "stdout", "--psm", "6"], {
      maxBuffer: MAX_FILE_BUFFER,
      timeout: COMMAND_TIMEOUT_MS
    });
    return limitTextContent(stdout);
  } catch {
    return "";
  }
}
async function readLocalResourceText(filePath) {
  try {
    const stats = await fs2.stat(filePath);
    if (!stats.isFile()) {
      return "";
    }
  } catch {
    return "";
  }
  const extension = path3.extname(filePath).toLowerCase();
  const mimeType = await detectLocalMimeType(filePath);
  if (IMAGE_EXTENSIONS.has(extension) || isLikelyImageMimeType(mimeType)) {
    return await readTextViaTesseract(filePath) || await readTextViaMetadata(filePath);
  }
  if (TEXT_EXTENSIONS.has(extension) || isLikelyTextMimeType(mimeType)) {
    return readTextFile(filePath);
  }
  if (TEXTUTIL_EXTENSIONS.has(extension)) {
    return await readTextViaTextutil(filePath) || await readTextViaMetadata(filePath);
  }
  return await readTextViaMetadata(filePath) || await readTextViaStrings(filePath);
}
async function readRemoteBuffer(location) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), COMMAND_TIMEOUT_MS);
  try {
    const response = await fetch(location, {
      redirect: "follow",
      signal: controller.signal
    });
    if (!response.ok) {
      return void 0;
    }
    const contentLength = Number(response.headers.get("content-length") || "0");
    if (contentLength > MAX_REMOTE_BUFFER) {
      return void 0;
    }
    const arrayBuffer = await response.arrayBuffer();
    const buffer = Buffer.from(arrayBuffer);
    if (buffer.byteLength > MAX_REMOTE_BUFFER) {
      return void 0;
    }
    return {
      buffer,
      contentType: (response.headers.get("content-type") || "").toLowerCase()
    };
  } catch {
    return void 0;
  } finally {
    clearTimeout(timer);
  }
}
async function withTemporaryFile(extension, buffer, task) {
  const tempPath = path3.join(os.tmpdir(), `ju-hong-e-security-${Date.now()}-${Math.random().toString(16).slice(2)}${extension}`);
  try {
    await fs2.writeFile(tempPath, buffer);
    return await task(tempPath);
  } finally {
    await fs2.rm(tempPath, { force: true });
  }
}
async function readRemoteResourceText(location) {
  const response = await readRemoteBuffer(location);
  if (!response) {
    return "";
  }
  let extension = "";
  try {
    extension = path3.extname(new URL(location).pathname).toLowerCase();
  } catch {
    extension = "";
  }
  if (IMAGE_EXTENSIONS.has(extension) || isLikelyImageMimeType(response.contentType)) {
    return withTemporaryFile(extension || ".img", response.buffer, readTextViaTesseract);
  }
  if (TEXT_EXTENSIONS.has(extension) || isLikelyTextMimeType(response.contentType)) {
    return limitTextContent(response.buffer.toString("utf8"));
  }
  if (TEXTUTIL_EXTENSIONS.has(extension)) {
    return withTemporaryFile(extension, response.buffer, async (filePath) => await readTextViaTextutil(filePath) || await readTextViaMetadata(filePath));
  }
  return "";
}
async function collectReferencedResourceContents(values, rootDir) {
  const resources = toReferencedResources(values, rootDir);
  const contents = [];
  for (const resource of resources) {
    const content = resource.kind === "local-file" ? await readLocalResourceText(resource.location) : await readRemoteResourceText(resource.location);
    if (!content) {
      continue;
    }
    contents.push({
      location: resource.location,
      value: content
    });
  }
  return contents;
}

// 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;
var GLOBAL_VALIDATOR_RULES = securityRegistryState.validatorRules;
function resetRegex(pattern) {
  pattern.lastIndex = 0;
  return pattern;
}
function collectStringValues(value) {
  if (typeof value === "string") {
    return value.trim() ? [value] : [];
  }
  if (Array.isArray(value)) {
    return value.flatMap((item) => collectStringValues(item));
  }
  if (value && typeof value === "object") {
    return Object.values(value).flatMap((item) => collectStringValues(item));
  }
  return [];
}
function collectCandidateValues(value, source) {
  return collectStringValues(value).map((entry) => ({
    source,
    value: entry
  }));
}
async function collectSecurityStringValues(payload, options) {
  const directValues = [
    ...collectCandidateValues(payload.input, "input"),
    ...collectCandidateValues(payload.rawCommand, "rawCommand"),
    ...collectCandidateValues(payload.rawArgs, "rawArgs"),
    ...collectCandidateValues(payload.args, "args"),
    ...options.inspectPrompt ? collectCandidateValues(payload.prompt, "prompt") : []
  ];
  if (!options.inspectResources) {
    return directValues;
  }
  const referencedContents = await collectReferencedResourceContents(
    directValues.map((entry) => entry.value),
    payload.promptRootDir
  );
  return [
    ...directValues,
    ...referencedContents.map(
      (entry) => ({
        location: entry.location,
        source: "resource",
        value: entry.value
      })
    )
  ];
}
function getPatternRules(config) {
  return [...GLOBAL_PATTERN_RULES.values(), ...config?.patterns || []];
}
function getValidatorRules(config) {
  return [...GLOBAL_VALIDATOR_RULES.values(), ...config?.validators || []];
}
function addGlobalSecurityPattern(rule) {
  GLOBAL_PATTERN_RULES.set(rule.name, rule);
}
async function validateSecurityPayload(payload, config, options = {
  inspectPrompt: true,
  inspectResources: true,
  mode: "prompt-with-resources"
}) {
  const stringValues = await collectSecurityStringValues(payload, options);
  for (const rule of getPatternRules(config)) {
    const matched = findMatchedCandidate(stringValues, rule);
    if (matched) {
      return {
        detail: {
          location: matched.location,
          matchedText: matched.matchedText,
          source: matched.source
        },
        message: rule.message,
        ok: false,
        ruleName: rule.name
      };
    }
  }
  for (const rule of getValidatorRules(config)) {
    const result = await rule.validate(payload);
    if (result === true) {
      continue;
    }
    return {
      detail: {
        source: payload.prompt ? "prompt" : payload.input ? "input" : "args"
      },
      message: typeof result === "string" && result.trim() ? result : rule.message,
      ok: false,
      ruleName: rule.name
    };
  }
  return {
    ok: true
  };
}
function findMatchedCandidate(stringValues, rule) {
  for (const candidate of stringValues) {
    const matchedText = extractMatchedText(candidate.value, rule);
    if (!matchedText) {
      continue;
    }
    return {
      location: candidate.location,
      matchedText,
      source: candidate.source
    };
  }
  return void 0;
}
function extractMatchedText(value, rule) {
  const match = resetRegex(rule.pattern).exec(value);
  if (!match?.[0]) {
    return "";
  }
  const formattedMatch = rule.formatMatch ? rule.formatMatch(match[0]) : match[0];
  return safeExcerpt(formattedMatch, 120);
}

// 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/
  });
}

// src/features/security-policy/domain/policy.ts
var DEFAULT_SECURITY_POLICY_MODE = "prompt-with-resources";
var SECURITY_POLICY_OPTIONS = [
  {
    description: "\uBCF4\uC548 \uAC80\uC0AC\uB97C \uC644\uC804\uD788 \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4. \uBBFC\uAC10\uC815\uBCF4\uAC00 \uD3EC\uD568\uB418\uC5B4\uB3C4 \uCC28\uB2E8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
    label: "\uBCF4\uC548 \uAC80\uC0AC \uC0AC\uC6A9 \uC548 \uD568",
    mode: "disabled",
    summary: "\uBCF4\uC548 \uAC80\uC0AC \uBE44\uD65C\uC131\uD654"
  },
  {
    description: "\uC0AC\uC6A9\uC790 \uC785\uB825\uACFC \uBA85\uB839 \uC778\uC790\uB9CC \uAC80\uC0AC\uD569\uB2C8\uB2E4. \uD504\uB86C\uD504\uD2B8 \uBCF8\uBB38\uACFC \uCC38\uC870 \uB9AC\uC18C\uC2A4\uB294 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
    label: "\uC785\uB825/\uBA85\uB839\uB9CC \uAC80\uC0AC",
    mode: "input-only",
    summary: "\uC785\uB825/\uBA85\uB839 \uBB38\uC790\uC5F4\uB9CC \uAC80\uC0AC"
  },
  {
    description: "\uC785\uB825\uACFC AI \uD504\uB86C\uD504\uD2B8 \uBB38\uC790\uC5F4\uAE4C\uC9C0 \uAC80\uC0AC\uD569\uB2C8\uB2E4. \uACBD\uB85C/URL\uC774 \uAC00\uB9AC\uD0A4\uB294 \uB0B4\uC6A9\uC740 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
    label: "\uD504\uB86C\uD504\uD2B8 \uD14D\uC2A4\uD2B8\uAE4C\uC9C0 \uAC80\uC0AC",
    mode: "prompt-only",
    summary: "\uD504\uB86C\uD504\uD2B8 \uBB38\uC790\uC5F4\uAE4C\uC9C0 \uAC80\uC0AC"
  },
  {
    description: "\uC785\uB825, \uD504\uB86C\uD504\uD2B8, \uACBD\uB85C/URL\uC774 \uAC00\uB9AC\uD0A4\uB294 \uCC38\uC870 \uB9AC\uC18C\uC2A4 \uB0B4\uC6A9\uAE4C\uC9C0 \uD568\uAED8 \uAC80\uC0AC\uD569\uB2C8\uB2E4.",
    label: "\uD504\uB86C\uD504\uD2B8\uC640 \uCC38\uC870 \uB9AC\uC18C\uC2A4\uAE4C\uC9C0 \uC2EC\uCE35 \uAC80\uC0AC",
    mode: "prompt-with-resources",
    summary: "\uD504\uB86C\uD504\uD2B8\uC640 \uCC38\uC870 \uB9AC\uC18C\uC2A4\uAE4C\uC9C0 \uC2EC\uCE35 \uAC80\uC0AC"
  }
];
function createDefaultSecurityPolicy() {
  return {
    mode: DEFAULT_SECURITY_POLICY_MODE
  };
}
function isSecurityPolicyMode(value) {
  return SECURITY_POLICY_OPTIONS.some((option) => option.mode === value);
}
function getSecurityPolicyOption(mode) {
  return SECURITY_POLICY_OPTIONS.find((option) => option.mode === mode) || SECURITY_POLICY_OPTIONS.at(-1);
}
function describeSecurityPolicyMode(mode) {
  return getSecurityPolicyOption(mode).label;
}
function isSecurityPolicyEnabled(mode) {
  return mode !== "disabled";
}
function resolveSecurityValidationOptions(mode) {
  switch (mode) {
    case "disabled":
      return {
        inspectPrompt: false,
        inspectResources: false,
        mode
      };
    case "input-only":
      return {
        inspectPrompt: false,
        inspectResources: false,
        mode
      };
    case "prompt-only":
      return {
        inspectPrompt: true,
        inspectResources: false,
        mode
      };
    case "prompt-with-resources":
    default:
      return {
        inspectPrompt: true,
        inspectResources: true,
        mode
      };
  }
}
function readSecurityPolicy(paths) {
  if (!paths?.securityPolicyPath || !fs.existsSync(paths.securityPolicyPath)) {
    return createDefaultSecurityPolicy();
  }
  try {
    const parsed = JSON.parse(fs.readFileSync(paths.securityPolicyPath, "utf8"));
    if (!isSecurityPolicyMode(parsed.mode)) {
      return createDefaultSecurityPolicy();
    }
    return {
      mode: parsed.mode
    };
  } catch {
    return createDefaultSecurityPolicy();
  }
}

// src/platform/request-security/guard.ts
function toSecuritySourceLabel(source, location) {
  switch (source) {
    case "input":
      return "\uC0AC\uC6A9\uC790 \uC785\uB825";
    case "rawCommand":
      return "\uC6D0\uBCF8 \uBA85\uB839\uC5B4";
    case "rawArgs":
      return "\uC6D0\uBCF8 \uBA85\uB839 \uC778\uC790";
    case "args":
      return "\uBA85\uB839 \uC778\uC790";
    case "prompt":
      return "AI \uD504\uB86C\uD504\uD2B8";
    case "resource":
      return location ? `\uCC38\uC870 \uB9AC\uC18C\uC2A4 (${location})` : "\uCC38\uC870 \uB9AC\uC18C\uC2A4";
    default:
      return source;
  }
}
function buildSecurityBlockSections(result, policyModeLabel) {
  const detailLines = [`- policyMode: ${policyModeLabel}`, `- rule: \`${result.ruleName}\``, `- message: ${result.message}`];
  if (result.detail) {
    detailLines.push(`- source: ${toSecuritySourceLabel(result.detail.source, result.detail.location)}`);
    if (result.detail.matchedText) {
      detailLines.push(`- matched: \`${result.detail.matchedText}\``);
    }
  }
  return [
    {
      heading: "Security Block",
      markdown: detailLines.join("\n")
    }
  ];
}
function buildSecurityBlockUserMessage(result, policyModeLabel, errorReportPath) {
  const lines = ["\uBCF4\uC548 \uC815\uCC45\uC5D0 \uC758\uD574 \uC694\uCCAD\uC744 \uC911\uB2E8\uD588\uC2B5\uB2C8\uB2E4.", result.message, `- \uD604\uC7AC \uC815\uCC45: ${policyModeLabel}`, `- \uBCF4\uC548 \uADDC\uCE59: \`${result.ruleName}\``];
  if (result.detail) {
    lines.push(`- \uAC10\uC9C0 \uC704\uCE58: ${toSecuritySourceLabel(result.detail.source, result.detail.location)}`);
    if (result.detail.matchedText) {
      lines.push(`- \uAC10\uC9C0 \uB0B4\uC6A9: \`${result.detail.matchedText}\``);
    }
  }
  if (errorReportPath) {
    lines.push(`- \uC5D0\uB7EC \uB9AC\uD3EC\uD2B8: ${errorReportPath}`);
  }
  return lines.join("\n");
}
async function guardSecurityPayload(options) {
  ensureDefaultSecurityRules();
  const policy = readSecurityPolicy(options.paths);
  const policyModeLabel = describeSecurityPolicyMode(policy.mode);
  if (!isSecurityPolicyEnabled(policy.mode)) {
    options.trace("security:skip", `${options.traceLabel} | ${policy.mode}`);
    return {
      ok: true
    };
  }
  const validationOptions = resolveSecurityValidationOptions(policy.mode);
  const result = await validateSecurityPayload(options.payload, options.config, validationOptions);
  if (!result.ok) {
    options.trace("security:block", `${options.traceLabel} | ${result.ruleName}`);
    const errorReportPath = options.paths ? writeErrorReport(
      options.paths,
      {
        detail: result.detail,
        message: result.message,
        name: "SecurityPolicyBlockedError",
        payload: {
          command: options.payload.command,
          service: options.payload.service
        },
        ruleName: result.ruleName
      },
      {
        extraSections: buildSecurityBlockSections(result, policyModeLabel),
        scope: options.reportScope || `security:${options.traceLabel}`
      }
    ) : void 0;
    const userMessage = buildSecurityBlockUserMessage(result, policyModeLabel, errorReportPath);
    console.error(userMessage);
    return {
      ...result,
      errorReportPath,
      userMessage
    };
  }
  return result;
}

// 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 sortByOrder(commands) {
  return [...commands].sort((left, right) => {
    const leftOrder = left.order ?? Number.MAX_SAFE_INTEGER;
    const rightOrder = right.order ?? Number.MAX_SAFE_INTEGER;
    if (leftOrder !== rightOrder) {
      return leftOrder - rightOrder;
    }
    return left.command.localeCompare(right.command);
  });
}
function toBuiltinSlashCommandOption(command) {
  return {
    command: command.command,
    description: command.description,
    insertValue: command.insertValue || command.command,
    matchKeywords: command.matchKeywords
  };
}
function resolveTelemetryStatusFromError(error) {
  if (isUserCancelledError(error)) {
    return "cancelled";
  }
  if (isUserTerminatedError(error)) {
    return "terminated";
  }
  return "error";
}
async function validateCommand(context, security) {
  const result = await guardSecurityPayload({
    config: security,
    paths: context.paths,
    payload: {
      args: context.args,
      command: context.command,
      input: context.input,
      rawArgs: context.rawArgs,
      rawCommand: context.rawCommand,
      service: context.service
    },
    reportScope: `security:${context.command}`,
    trace: context.trace,
    traceLabel: context.command
  });
  return result.ok;
}
function clearCommandRegistry() {
  JU_HONG_E_COMMANDS.clear();
}
function applyBuiltinCommandFilter(allowedCommands) {
  if (!allowedCommands) {
    return;
  }
  for (const commandName of [...JU_HONG_E_COMMANDS.keys()]) {
    if (!allowedCommands.has(commandName)) {
      JU_HONG_E_COMMANDS.delete(commandName);
    }
  }
}
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);
}
function getBuiltinCommands() {
  return sortByOrder([...JU_HONG_E_COMMANDS.values()]);
}
function getBuiltinCommandNames() {
  return getBuiltinCommands().map((command) => command.command);
}
function getBuiltinSlashCommands() {
  return getBuiltinCommands().map(toBuiltinSlashCommandOption);
}
function getSessionCommandCatalog() {
  const builtinCommands = getBuiltinCommands();
  return {
    builtinCommands,
    slashCommands: builtinCommands.map(toBuiltinSlashCommandOption)
  };
}
function findJuHongECommand(command) {
  return JU_HONG_E_COMMANDS.get(command);
}
async function executeJuHongECommand(definition, context) {
  beginSlashCommandTelemetryInputCollection(context.args);
  const resolveTelemetryArgs = () => endSlashCommandTelemetryInputCollection();
  try {
    const canExecute = await validateCommand(context, definition.security);
    if (!canExecute) {
      trackSlashCommandExecution({
        args: resolveTelemetryArgs(),
        command: context.command,
        kind: "builtin",
        rootDir: context.paths.rootDir,
        service: context.service,
        status: "blocked",
        trace: context.trace
      });
      return {};
    }
    const result = await definition.execute({
      ...context,
      definition
    });
    trackSlashCommandExecution({
      args: resolveTelemetryArgs(),
      command: context.command,
      kind: "builtin",
      rootDir: context.paths.rootDir,
      service: context.service,
      status: "success",
      trace: context.trace
    });
    return result;
  } catch (error) {
    trackSlashCommandExecution({
      args: resolveTelemetryArgs(),
      command: context.command,
      kind: "builtin",
      rootDir: context.paths.rootDir,
      service: context.service,
      status: resolveTelemetryStatusFromError(error),
      trace: context.trace
    });
    throw error;
  }
}

export { addCommand, applyBuiltinCommandFilter, clearCommandRegistry, executeJuHongECommand, findJuHongECommand, getBuiltinCommandNames, getBuiltinCommands, getBuiltinSlashCommands, getSessionCommandCatalog };
