{"version":3,"sources":["../core/utils/ansi-processor.ts","../interpreter/streaming/template-interpolator.ts"],"names":["ANSI_CODES","reset","bold","dim","italic","underline","blink","inverse","hidden","strikethrough","black","red","green","yellow","blue","magenta","cyan","white","bright_black","bright_red","bright_green","bright_yellow","bright_blue","bright_magenta","bright_cyan","bright_white","bg_black","bg_red","bg_green","bg_yellow","bg_blue","bg_magenta","bg_cyan","bg_white","bg_bright_black","bg_bright_red","bg_bright_green","bg_bright_yellow","bg_bright_blue","bg_bright_magenta","bg_bright_cyan","bg_bright_white","gray","grey","bg_gray","bg_grey","brightblack","brightred","brightgreen","brightyellow","brightblue","brightmagenta","brightcyan","brightwhite","bgblack","bgred","bggreen","bgyellow","bgblue","bgmagenta","bgcyan","bgwhite","CODE_PATTERN","ANSI_ESCAPE_PATTERN","shouldProcessAnsi","target","options","process","env","NO_COLOR","MLLD_NO_COLOR","enabled","forceTTY","MLLD_FORCE_COLOR","stdout","isTTY","stderr","expandAnsiCodes","text","replace","match","code","lowerCode","toLowerCase","stripAnsiMarkers","stripAnsiEscapes","processAnsi","getFormattedText","plain","ansi","getAvailableCodes","Object","keys","interpolateTemplate","template","eventData","format","missingValue","result","replaceVariables","processEscapes","variablePattern","_match","path","value","extractPath","returnUndefined","undefined","formatValue","JSON","stringify","String","Array","isArray","applyTemplates","templates","json","DEFAULT_TEMPLATES","thinking","message","toolUse","toolResult","error","metadata"],"mappings":"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","file":"chunk-NS36QLDY.mjs","sourcesContent":["/**\n * ANSI Color Processing\n *\n * Handles `%color%` syntax for terminal colors in mlld output.\n * Colors are processed at the effect handler level, not during interpolation.\n *\n * Supported codes:\n * - Colors: %red%, %green%, %blue%, %yellow%, %cyan%, %magenta%, %white%, %black%\n * - Bright colors: %bright_red%, %bright_green%, etc.\n * - Backgrounds: %bg_red%, %bg_green%, etc.\n * - Modifiers: %bold%, %dim%, %italic%, %underline%, %blink%, %inverse%, %hidden%, %strikethrough%\n * - Reset: %reset%\n *\n * Environment variables:\n * - MLLD_NO_COLOR=true: Strip all ANSI codes\n * - MLLD_FORCE_COLOR=true: Force ANSI codes even when not TTY\n * - NO_COLOR: Standard no-color env var\n */\n\nconst ANSI_CODES: Record<string, string> = {\n  // Reset\n  reset: '\\x1b[0m',\n\n  // Modifiers\n  bold: '\\x1b[1m',\n  dim: '\\x1b[2m',\n  italic: '\\x1b[3m',\n  underline: '\\x1b[4m',\n  blink: '\\x1b[5m',\n  inverse: '\\x1b[7m',\n  hidden: '\\x1b[8m',\n  strikethrough: '\\x1b[9m',\n\n  // Regular colors (foreground)\n  black: '\\x1b[30m',\n  red: '\\x1b[31m',\n  green: '\\x1b[32m',\n  yellow: '\\x1b[33m',\n  blue: '\\x1b[34m',\n  magenta: '\\x1b[35m',\n  cyan: '\\x1b[36m',\n  white: '\\x1b[37m',\n\n  // Bright colors (foreground)\n  bright_black: '\\x1b[90m',\n  bright_red: '\\x1b[91m',\n  bright_green: '\\x1b[92m',\n  bright_yellow: '\\x1b[93m',\n  bright_blue: '\\x1b[94m',\n  bright_magenta: '\\x1b[95m',\n  bright_cyan: '\\x1b[96m',\n  bright_white: '\\x1b[97m',\n\n  // Background colors\n  bg_black: '\\x1b[40m',\n  bg_red: '\\x1b[41m',\n  bg_green: '\\x1b[42m',\n  bg_yellow: '\\x1b[43m',\n  bg_blue: '\\x1b[44m',\n  bg_magenta: '\\x1b[45m',\n  bg_cyan: '\\x1b[46m',\n  bg_white: '\\x1b[47m',\n\n  // Bright background colors\n  bg_bright_black: '\\x1b[100m',\n  bg_bright_red: '\\x1b[101m',\n  bg_bright_green: '\\x1b[102m',\n  bg_bright_yellow: '\\x1b[103m',\n  bg_bright_blue: '\\x1b[104m',\n  bg_bright_magenta: '\\x1b[105m',\n  bg_bright_cyan: '\\x1b[106m',\n  bg_bright_white: '\\x1b[107m',\n\n  // Aliases for convenience\n  gray: '\\x1b[90m',\n  grey: '\\x1b[90m',\n  bg_gray: '\\x1b[100m',\n  bg_grey: '\\x1b[100m',\n\n  // Aliases without underscores\n  brightblack: '\\x1b[90m',\n  brightred: '\\x1b[91m',\n  brightgreen: '\\x1b[92m',\n  brightyellow: '\\x1b[93m',\n  brightblue: '\\x1b[94m',\n  brightmagenta: '\\x1b[95m',\n  brightcyan: '\\x1b[96m',\n  brightwhite: '\\x1b[97m',\n  bgblack: '\\x1b[40m',\n  bgred: '\\x1b[41m',\n  bggreen: '\\x1b[42m',\n  bgyellow: '\\x1b[43m',\n  bgblue: '\\x1b[44m',\n  bgmagenta: '\\x1b[45m',\n  bgcyan: '\\x1b[46m',\n  bgwhite: '\\x1b[47m'\n};\n\n// Pattern to match %code% sequences\nconst CODE_PATTERN = /%([a-z_]+)%/gi;\n\n// Pattern to match actual ANSI escape sequences\nconst ANSI_ESCAPE_PATTERN = /\\x1b\\[[0-9;]*m/g;\n\nexport interface AnsiProcessingOptions {\n  enabled?: boolean;\n  forceTTY?: boolean;\n}\n\n/**\n * Check if ANSI processing should be enabled for a target\n */\nexport function shouldProcessAnsi(\n  target: 'stdout' | 'stderr' | 'file' | 'doc',\n  options?: AnsiProcessingOptions\n): boolean {\n  // Check environment variables\n  if (process.env.NO_COLOR || process.env.MLLD_NO_COLOR === 'true') {\n    return false;\n  }\n\n  // Force option overrides\n  if (options?.enabled === false) {\n    return false;\n  }\n  if (options?.forceTTY || process.env.MLLD_FORCE_COLOR === 'true') {\n    return true;\n  }\n\n  // File output never gets ANSI\n  if (target === 'file') {\n    return false;\n  }\n\n  // Doc buffer doesn't get ANSI by default (preserved for later processing)\n  if (target === 'doc') {\n    return false;\n  }\n\n  // Check TTY status\n  if (target === 'stdout') {\n    return process.stdout.isTTY === true;\n  }\n  if (target === 'stderr') {\n    return process.stderr.isTTY === true;\n  }\n\n  return false;\n}\n\n/**\n * Expand %color% codes to ANSI escape sequences\n */\nexport function expandAnsiCodes(text: string): string {\n  return text.replace(CODE_PATTERN, (match, code) => {\n    const lowerCode = code.toLowerCase();\n    return ANSI_CODES[lowerCode] ?? match;\n  });\n}\n\n/**\n * Strip %color% codes from text (removes the markers without replacing)\n */\nexport function stripAnsiMarkers(text: string): string {\n  return text.replace(CODE_PATTERN, '');\n}\n\n/**\n * Strip actual ANSI escape sequences from text\n */\nexport function stripAnsiEscapes(text: string): string {\n  return text.replace(ANSI_ESCAPE_PATTERN, '');\n}\n\n/**\n * Check if text contains %color% markers\n */\nexport function hasAnsiMarkers(text: string): boolean {\n  return CODE_PATTERN.test(text);\n}\n\n/**\n * Check if text contains actual ANSI escape sequences\n */\nexport function hasAnsiEscapes(text: string): boolean {\n  return ANSI_ESCAPE_PATTERN.test(text);\n}\n\n/**\n * Process text for a specific output target\n *\n * - For TTY stdout/stderr: Expands %color% to ANSI codes\n * - For non-TTY or file: Strips %color% markers\n */\nexport function processAnsi(\n  text: string,\n  target: 'stdout' | 'stderr' | 'file' | 'doc',\n  options?: AnsiProcessingOptions\n): string {\n  if (shouldProcessAnsi(target, options)) {\n    return expandAnsiCodes(text);\n  }\n  return stripAnsiMarkers(text);\n}\n\n/**\n * Get both plain and formatted versions of text\n */\nexport function getFormattedText(text: string): { plain: string; ansi: string } {\n  return {\n    plain: stripAnsiMarkers(text),\n    ansi: expandAnsiCodes(text)\n  };\n}\n\n/**\n * List all available ANSI codes\n */\nexport function getAvailableCodes(): string[] {\n  return Object.keys(ANSI_CODES);\n}\n","/**\n * Template Interpolator for Streaming Adapters\n *\n * Interpolates templates with event data and format-specific processing.\n *\n * Supported syntax:\n * - Variable references: `@evt.field`, `@evt.nested.field`\n * - Escape sequences: `@@` → `@`, `%%` → `%`\n * - ANSI color codes: `%red%`, `%bold%` (processed based on format)\n *\n * Output formats:\n * - `text`: Plain text with variables replaced\n * - `ansi`: Variables replaced + ANSI codes expanded\n * - `json`: Variables JSON-stringified appropriately\n */\n\nimport { expandAnsiCodes, stripAnsiMarkers } from '@core/utils/ansi-processor';\nimport { extractPath } from './jsonpath';\n\nexport type TemplateFormat = 'text' | 'ansi' | 'json';\n\nexport interface InterpolateOptions {\n  missingValue?: string;\n  escapeHtml?: boolean;\n}\n\n/**\n * Interpolate a template with event data.\n *\n * @param template - Template string with `@evt.*` placeholders\n * @param eventData - Data extracted from the event\n * @param format - Output format ('text', 'ansi', or 'json')\n * @param options - Additional options\n * @returns Interpolated string\n */\nexport function interpolateTemplate(\n  template: string,\n  eventData: Record<string, unknown>,\n  format: TemplateFormat = 'text',\n  options?: InterpolateOptions\n): string {\n  const { missingValue = '' } = options ?? {};\n\n  // Step 1: Replace @evt.* variables\n  let result = replaceVariables(template, eventData, format, missingValue);\n\n  // Step 2: Process ANSI codes based on format\n  // (Do this BEFORE escape processing so %bold%%red% works correctly)\n  if (format === 'ansi') {\n    result = expandAnsiCodes(result);\n  } else if (format === 'text' || format === 'json') {\n    result = stripAnsiMarkers(result);\n  }\n\n  // Step 3: Process escape sequences (after ANSI so %% escapes work)\n  result = processEscapes(result);\n\n  return result;\n}\n\n/**\n * Replace @evt.* variables in a template.\n */\nfunction replaceVariables(\n  template: string,\n  eventData: Record<string, unknown>,\n  format: TemplateFormat,\n  missingValue: string\n): string {\n  // Match @evt.path or @evt[index].path patterns\n  // Uses negative lookbehind to skip escaped @@\n  const variablePattern = /(?<!@)@evt\\.([a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*|\\[\\d+\\])*)/g;\n\n  return template.replace(variablePattern, (_match, path: string) => {\n    const value = extractPath(eventData, path, { returnUndefined: true });\n\n    if (value === undefined) {\n      return missingValue;\n    }\n\n    return formatValue(value, format);\n  });\n}\n\n/**\n * Format a value for output based on format type.\n */\nfunction formatValue(value: unknown, format: TemplateFormat): string {\n  if (value === null) {\n    return format === 'json' ? 'null' : '';\n  }\n\n  if (value === undefined) {\n    return format === 'json' ? 'null' : '';\n  }\n\n  if (typeof value === 'string') {\n    if (format === 'json') {\n      // JSON format: quote strings\n      return JSON.stringify(value);\n    }\n    // text/ansi: use raw string\n    return value;\n  }\n\n  if (typeof value === 'number' || typeof value === 'boolean') {\n    // Numbers and booleans: no quoting needed\n    return String(value);\n  }\n\n  if (Array.isArray(value) || typeof value === 'object') {\n    // Objects and arrays: always stringify\n    return JSON.stringify(value);\n  }\n\n  return String(value);\n}\n\n/**\n * Process escape sequences in a template.\n * - @@ → @\n * - %% → %\n */\nfunction processEscapes(text: string): string {\n  return text\n    .replace(/@@/g, '@')\n    .replace(/%%/g, '%');\n}\n\n/**\n * Apply templates to event data for all output formats.\n *\n * Returns an object with plain, ansi, and optionally json formats.\n */\nexport interface FormattedOutput {\n  plain: string;\n  ansi: string;\n  json?: string;\n}\n\nexport interface EventTemplates {\n  text?: string;\n  ansi?: string;\n  json?: string;\n}\n\n/**\n * Apply templates to produce formatted output in multiple formats.\n */\nexport function applyTemplates(\n  eventData: Record<string, unknown>,\n  templates: EventTemplates,\n  options?: InterpolateOptions\n): FormattedOutput {\n  const result: FormattedOutput = {\n    plain: '',\n    ansi: ''\n  };\n\n  // Use text template for plain output\n  if (templates.text) {\n    result.plain = interpolateTemplate(templates.text, eventData, 'text', options);\n  }\n\n  // Use ansi template for colored output, fallback to text\n  if (templates.ansi) {\n    result.ansi = interpolateTemplate(templates.ansi, eventData, 'ansi', options);\n  } else if (templates.text) {\n    result.ansi = interpolateTemplate(templates.text, eventData, 'text', options);\n  }\n\n  // Use json template if specified\n  if (templates.json) {\n    result.json = interpolateTemplate(templates.json, eventData, 'json', options);\n  }\n\n  return result;\n}\n\n/**\n * Check if a string contains template variables.\n */\nexport function hasTemplateVariables(template: string): boolean {\n  return /(?<!@)@evt\\.[a-zA-Z_]/.test(template);\n}\n\n/**\n * Extract variable paths from a template.\n */\nexport function extractVariablePaths(template: string): string[] {\n  const variablePattern = /(?<!@)@evt\\.([a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*|\\[\\d+\\])*)/g;\n  const paths: string[] = [];\n  let match;\n\n  while ((match = variablePattern.exec(template)) !== null) {\n    paths.push(match[1]);\n  }\n\n  return paths;\n}\n\n/**\n * Create a simple template that outputs a single field.\n */\nexport function createFieldTemplate(fieldName: string): string {\n  return `@evt.${fieldName}`;\n}\n\n/**\n * Create default templates for common event types.\n */\nexport const DEFAULT_TEMPLATES = {\n  thinking: {\n    text: '@evt.text',\n    ansi: '%dim%@evt.text%reset%'\n  },\n  message: {\n    text: '@evt.chunk',\n    ansi: '@evt.chunk'\n  },\n  toolUse: {\n    text: '[@evt.name] @evt.input',\n    ansi: '%cyan%[@evt.name]%reset% @evt.input'\n  },\n  toolResult: {\n    text: '[@evt.toolUseId] @evt.result',\n    ansi: '%green%[@evt.toolUseId]%reset% @evt.result'\n  },\n  error: {\n    text: 'Error: @evt.message',\n    ansi: '%red%Error:%reset% @evt.message'\n  },\n  metadata: {\n    text: 'Tokens: @evt.inputTokens in / @evt.outputTokens out',\n    ansi: '%dim%Tokens: @evt.inputTokens in / @evt.outputTokens out%reset%'\n  }\n};\n"]}