@tuicomponents/core 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/component.ts","../src/registry.ts","../src/width.ts","../src/terminal.ts","../src/detection.ts","../src/markdown.ts","../src/styling.ts","../src/theme.ts","../src/wrap.ts"],"sourcesContent":["// Component system\nexport {\n type RenderMode,\n type ComponentExample,\n type ComponentMetadata,\n type RenderContext,\n type RenderResult,\n type TuiComponent,\n type ComponentFactory,\n BaseTuiComponent,\n} from \"./component.js\";\n\n// Component registry\nexport { type ComponentInfo, ComponentRegistry, registry } from \"./registry.js\";\n\n// Width utilities\nexport {\n getStringWidth,\n padToWidth,\n truncateToWidth,\n measureLines,\n type PadOptions,\n type TruncateOptions,\n} from \"./width.js\";\n\n// Terminal utilities\nexport {\n getTerminalSize,\n getTerminalWidth,\n isTTY,\n detectColorLevel,\n createRenderContext,\n type CreateRenderContextOptions,\n DEFAULT_TERMINAL_WIDTH,\n DEFAULT_TERMINAL_HEIGHT,\n} from \"./terminal.js\";\n\n// Theme and styling\nexport {\n type ChromatermTheme,\n type ChromatermColor,\n type ThemeOptions,\n type SemanticColors,\n type TuiTheme,\n createThemeSync,\n detectTheme,\n defaultTheme,\n} from \"./theme.js\";\n\n// Semantic styling\nexport { type StyleFunctions, createStyleFunctions } from \"./styling.js\";\n\n// Text wrapping\nexport { wrapText, wrapTextWithInfo, type WrapOptions } from \"./wrap.js\";\n\n// Environment detection\nexport {\n type ProcessAncestor,\n type EnvironmentDetection,\n getProcessTree,\n detectEnvironment,\n isRunningInAIAssistant,\n} from \"./detection.js\";\n\n// Markdown rendering utilities\nexport {\n type MarkdownStyle,\n DEFAULT_ANCHOR,\n inlineCode,\n anchorLine,\n applyMarkdownStyle,\n joinAnchoredLines,\n stripMarkdownFormatting,\n getMarkdownRenderedWidth,\n} from \"./markdown.js\";\n","import type { ZodType, ZodTypeDef } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { StyleFunctions } from \"./styling.js\";\nimport type { TuiTheme } from \"./theme.js\";\n\n/**\n * Render mode for component output.\n */\nexport type RenderMode = \"ansi\" | \"markdown\";\n\n/**\n * Example input/output pair for a component.\n */\nexport interface ComponentExample<TInput> {\n /** Human-readable name for this example */\n name: string;\n /** Description of what this example demonstrates */\n description?: string;\n /** The input data for this example */\n input: TInput;\n}\n\n/**\n * Metadata describing a TUI component.\n */\nexport interface ComponentMetadata<TInput> {\n /** Unique name for this component (e.g., \"table\", \"tree\") */\n name: string;\n /** Human-readable description */\n description: string;\n /** Semantic version */\n version: string;\n /** Usage examples */\n examples: ComponentExample<TInput>[];\n /**\n * Render modes this component supports.\n * If not specified, defaults to [\"ansi\"].\n */\n supportedModes?: RenderMode[];\n}\n\n/**\n * Context provided to components during rendering.\n */\nexport interface RenderContext {\n /** Available terminal width in columns */\n width: number;\n /** Whether output is going to a TTY */\n isTTY: boolean;\n /** Color support level: 0=none, 1=basic, 2=256, 3=truecolor */\n colorLevel: 0 | 1 | 2 | 3;\n /** Optional theme for styled output. If not provided, components render without colors. */\n theme?: TuiTheme;\n /**\n * Render mode for output.\n * - \"ansi\": Full ANSI escape codes for rich terminals\n * - \"markdown\": Markdown-friendly output for AI assistants\n * @default \"ansi\"\n */\n renderMode: RenderMode;\n /**\n * Semantic styling functions.\n *\n * Use these to apply consistent styling across render modes:\n * - ANSI mode: Applies theme colors (or passthrough if no theme)\n * - Markdown mode: Applies markdown formatting (backticks, bold, etc.)\n *\n * @example\n * ```ts\n * const styledBlocks = context.style.secondary(sparklineBlocks);\n * // ANSI: muted color\n * // Markdown: `sparklineBlocks`\n * ```\n */\n style: StyleFunctions;\n}\n\n/**\n * Result of rendering a component.\n */\nexport interface RenderResult {\n /** ANSI-formatted output string */\n output: string;\n /** Actual width of the widest line */\n actualWidth: number;\n /** Number of lines in the output */\n lineCount: number;\n}\n\n/**\n * A TUI component that renders structured data to terminal output.\n */\nexport interface TuiComponent<\n TInput,\n TSchema extends ZodType<TInput, ZodTypeDef, unknown> = ZodType<\n TInput,\n ZodTypeDef,\n unknown\n >,\n> {\n /** Component metadata */\n readonly metadata: ComponentMetadata<TInput>;\n /** Zod schema for input validation */\n readonly schema: TSchema;\n /**\n * Render the component with the given input and context.\n * @param input - Validated input data\n * @param context - Rendering context\n * @returns Rendered output with metadata\n */\n render(input: TInput, context: RenderContext): RenderResult;\n /**\n * Get JSON Schema representation of the input schema.\n * Used for CLI discovery and AI assistant integration.\n */\n getJsonSchema(): object;\n}\n\n/**\n * Factory function type for creating TUI components.\n */\nexport type ComponentFactory<\n TInput,\n TSchema extends ZodType<TInput, ZodTypeDef, unknown>,\n> = () => TuiComponent<TInput, TSchema>;\n\n/**\n * Base class helper for creating TUI components.\n * Provides default implementations for common functionality.\n */\nexport abstract class BaseTuiComponent<\n TInput,\n TSchema extends ZodType<TInput, ZodTypeDef, unknown>,\n> implements TuiComponent<TInput, TSchema> {\n abstract readonly metadata: ComponentMetadata<TInput>;\n abstract readonly schema: TSchema;\n\n abstract render(input: TInput, context: RenderContext): RenderResult;\n\n getJsonSchema(): object {\n // Use type assertion to avoid TypeScript's \"excessively deep\" type instantiation\n // error with complex nested Zod schemas when passed to zodToJsonSchema.\n // The ZodType constraint is safe here since TSchema already extends ZodType.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument\n return zodToJsonSchema(this.schema as any, {\n name: this.metadata.name,\n $refStrategy: \"none\",\n });\n }\n}\n","import type { TuiComponent } from \"./component.js\";\nimport type { ZodType, ZodTypeDef } from \"zod\";\n\n/**\n * Summary information about a registered component.\n */\nexport interface ComponentInfo {\n name: string;\n description: string;\n version: string;\n}\n\n/**\n * A registered component with unknown input type.\n * Used internally by the registry.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyComponent = TuiComponent<any, ZodType<any, ZodTypeDef, any>>;\n\n/**\n * Global registry for TUI components.\n * Enables CLI discovery and dynamic component lookup.\n */\nexport class ComponentRegistry {\n private components = new Map<string, AnyComponent>();\n\n /**\n * Register a component by invoking its factory function.\n * @param factory - Factory function that creates the component\n * @returns The created component instance\n */\n register<TInput, TSchema extends ZodType<TInput, ZodTypeDef, unknown>>(\n factory: () => TuiComponent<TInput, TSchema>\n ): TuiComponent<TInput, TSchema> {\n const component = factory();\n const name = component.metadata.name;\n\n if (this.components.has(name)) {\n throw new Error(`Component \"${name}\" is already registered`);\n }\n\n this.components.set(name, component as AnyComponent);\n return component;\n }\n\n /**\n * Get a component by name.\n * @param name - Component name\n * @returns The component or undefined if not found\n */\n get(name: string): AnyComponent | undefined {\n return this.components.get(name);\n }\n\n /**\n * Check if a component is registered.\n * @param name - Component name\n */\n has(name: string): boolean {\n return this.components.has(name);\n }\n\n /**\n * List all registered components.\n * @returns Array of component info objects\n */\n list(): ComponentInfo[] {\n return Array.from(this.components.values()).map((c) => ({\n name: c.metadata.name,\n description: c.metadata.description,\n version: c.metadata.version,\n }));\n }\n\n /**\n * Get all registered component names.\n */\n names(): string[] {\n return Array.from(this.components.keys());\n }\n\n /**\n * Clear all registered components.\n * Primarily useful for testing.\n */\n clear(): void {\n this.components.clear();\n }\n}\n\n/**\n * Global component registry instance.\n * Components register themselves here on import.\n */\nexport const registry = new ComponentRegistry();\n","import stringWidth from \"string-width\";\n\n/**\n * Get the visual width of a string in terminal columns.\n * Handles emoji, CJK characters, ANSI escape codes, and zero-width characters.\n *\n * @param str - The string to measure\n * @returns Width in terminal columns\n *\n * @example\n * ```ts\n * getStringWidth(\"hello\"); // 5\n * getStringWidth(\"δ½ ε₯½\"); // 4 (CJK characters are 2 columns each)\n * getStringWidth(\"πŸ‘‹\"); // 2 (emoji are typically 2 columns)\n * getStringWidth(\"\\x1b[31mred\\x1b[0m\"); // 3 (ANSI codes have 0 width)\n * ```\n */\nexport function getStringWidth(str: string): number {\n return stringWidth(str);\n}\n\n/**\n * Options for padding operations.\n */\nexport interface PadOptions {\n /** Character to use for padding (default: space) */\n padChar?: string;\n /** Alignment direction */\n align?: \"left\" | \"right\" | \"center\";\n}\n\n/**\n * Pad a string to a target width.\n * If the string is already wider than the target, it is returned unchanged.\n *\n * @param str - The string to pad\n * @param targetWidth - Target width in columns\n * @param options - Padding options\n * @returns Padded string\n *\n * @example\n * ```ts\n * padToWidth(\"hi\", 5); // \"hi \"\n * padToWidth(\"hi\", 5, { align: \"right\" }); // \" hi\"\n * padToWidth(\"hi\", 5, { align: \"center\" }); // \" hi \"\n * ```\n */\nexport function padToWidth(\n str: string,\n targetWidth: number,\n options: PadOptions = {}\n): string {\n const { padChar = \" \", align = \"left\" } = options;\n const currentWidth = getStringWidth(str);\n\n if (currentWidth >= targetWidth) {\n return str;\n }\n\n const padCharWidth = getStringWidth(padChar);\n if (padCharWidth === 0) {\n return str;\n }\n\n const paddingNeeded = targetWidth - currentWidth;\n const padCount = Math.floor(paddingNeeded / padCharWidth);\n const padding = padChar.repeat(padCount);\n\n switch (align) {\n case \"right\":\n return padding + str;\n case \"center\": {\n const leftPadCount = Math.floor(padCount / 2);\n const rightPadCount = padCount - leftPadCount;\n return padChar.repeat(leftPadCount) + str + padChar.repeat(rightPadCount);\n }\n case \"left\":\n default:\n return str + padding;\n }\n}\n\n/**\n * Options for truncation operations.\n */\nexport interface TruncateOptions {\n /** String to append when truncating (default: \"…\") */\n ellipsis?: string;\n /** Where to truncate: end or middle */\n position?: \"end\" | \"middle\";\n}\n\n/**\n * Truncate a string to fit within a target width.\n * If the string already fits, it is returned unchanged.\n *\n * @param str - The string to truncate\n * @param targetWidth - Maximum width in columns\n * @param options - Truncation options\n * @returns Truncated string\n *\n * @example\n * ```ts\n * truncateToWidth(\"hello world\", 8); // \"hello w…\"\n * truncateToWidth(\"hello world\", 8, { ellipsis: \"...\" }); // \"hello...\"\n * truncateToWidth(\"hello world\", 8, { position: \"middle\" }); // \"hel…rld\"\n * ```\n */\nexport function truncateToWidth(\n str: string,\n targetWidth: number,\n options: TruncateOptions = {}\n): string {\n const { ellipsis = \"…\", position = \"end\" } = options;\n const currentWidth = getStringWidth(str);\n\n if (currentWidth <= targetWidth) {\n return str;\n }\n\n const ellipsisWidth = getStringWidth(ellipsis);\n if (ellipsisWidth >= targetWidth) {\n // Ellipsis alone is too wide; just return what we can\n return truncateChars(str, targetWidth);\n }\n\n const availableWidth = targetWidth - ellipsisWidth;\n\n if (position === \"middle\") {\n const leftWidth = Math.ceil(availableWidth / 2);\n const rightWidth = Math.floor(availableWidth / 2);\n const leftPart = truncateChars(str, leftWidth);\n const rightPart = truncateCharsFromEnd(str, rightWidth);\n return leftPart + ellipsis + rightPart;\n }\n\n // position === \"end\"\n return truncateChars(str, availableWidth) + ellipsis;\n}\n\n/**\n * Truncate string to fit within width, character by character from the start.\n */\nfunction truncateChars(str: string, targetWidth: number): string {\n let result = \"\";\n let width = 0;\n\n for (const char of str) {\n const charWidth = getStringWidth(char);\n if (width + charWidth > targetWidth) {\n break;\n }\n result += char;\n width += charWidth;\n }\n\n return result;\n}\n\n/**\n * Get the last N columns of a string.\n */\nfunction truncateCharsFromEnd(str: string, targetWidth: number): string {\n // Collect characters using for-of which properly handles Unicode\n const collectedChars: string[] = [];\n for (const char of str) {\n collectedChars.push(char);\n }\n\n // Build result from end, character by character\n let result = \"\";\n let width = 0;\n\n for (let i = collectedChars.length - 1; i >= 0; i--) {\n const char = collectedChars[i];\n if (char === undefined) continue;\n const charWidth = getStringWidth(char);\n if (width + charWidth > targetWidth) {\n break;\n }\n result = char + result;\n width += charWidth;\n }\n\n return result;\n}\n\n/**\n * Split a string into lines and measure each line's width.\n *\n * @param str - The string to analyze\n * @returns Object with lines array and max width\n */\nexport function measureLines(str: string): {\n lines: string[];\n maxWidth: number;\n lineCount: number;\n} {\n const lines = str.split(\"\\n\");\n let maxWidth = 0;\n\n for (const line of lines) {\n const lineWidth = getStringWidth(line);\n if (lineWidth > maxWidth) {\n maxWidth = lineWidth;\n }\n }\n\n return {\n lines,\n maxWidth,\n lineCount: lines.length,\n };\n}\n","import terminalSize from \"terminal-size\";\nimport type { RenderContext, RenderMode } from \"./component.js\";\nimport { isRunningInAIAssistant } from \"./detection.js\";\nimport { createStyleFunctions } from \"./styling.js\";\nimport { defaultTheme, type TuiTheme } from \"./theme.js\";\n\n/**\n * Default terminal dimensions when size cannot be determined.\n */\nexport const DEFAULT_TERMINAL_WIDTH = 80;\nexport const DEFAULT_TERMINAL_HEIGHT = 24;\n\n/**\n * Get the current terminal size.\n *\n * @returns Object with columns and rows\n *\n * @example\n * ```ts\n * const { columns, rows } = getTerminalSize();\n * console.log(`Terminal is ${columns}x${rows}`);\n * ```\n */\nexport function getTerminalSize(): { columns: number; rows: number } {\n const size = terminalSize();\n return {\n columns: size.columns || DEFAULT_TERMINAL_WIDTH,\n rows: size.rows || DEFAULT_TERMINAL_HEIGHT,\n };\n}\n\n/**\n * Get the current terminal width.\n *\n * @returns Width in columns\n */\nexport function getTerminalWidth(): number {\n return getTerminalSize().columns;\n}\n\n/**\n * Check if stdout is a TTY.\n *\n * @returns true if running in a TTY\n */\nexport function isTTY(): boolean {\n // Access isTTY dynamically to handle both TTY and non-TTY streams\n const stdout = process.stdout as { isTTY?: boolean };\n return stdout.isTTY === true;\n}\n\n/**\n * Detect the color support level of the terminal.\n *\n * @returns Color level: 0=none, 1=basic (16), 2=256, 3=truecolor (16m)\n */\nexport function detectColorLevel(): 0 | 1 | 2 | 3 {\n // Respect NO_COLOR environment variable\n if (process.env[\"NO_COLOR\"] !== undefined) {\n return 0;\n }\n\n // Respect FORCE_COLOR environment variable\n const forceColor = process.env[\"FORCE_COLOR\"];\n if (forceColor !== undefined) {\n if (forceColor === \"0\" || forceColor === \"false\") {\n return 0;\n }\n if (forceColor === \"1\" || forceColor === \"true\" || forceColor === \"\") {\n return 1;\n }\n if (forceColor === \"2\") {\n return 2;\n }\n if (forceColor === \"3\") {\n return 3;\n }\n }\n\n // Not a TTY means no colors\n if (!isTTY()) {\n return 0;\n }\n\n // Check COLORTERM for truecolor support\n const colorTerm = process.env[\"COLORTERM\"];\n if (colorTerm === \"truecolor\" || colorTerm === \"24bit\") {\n return 3;\n }\n\n // Check TERM for 256 color support\n const term = process.env[\"TERM\"] ?? \"\";\n if (term.includes(\"256color\") || term.includes(\"256\")) {\n return 2;\n }\n\n // Check for basic color support\n if (\n term.includes(\"color\") ||\n term.includes(\"ansi\") ||\n term === \"xterm\" ||\n term === \"linux\"\n ) {\n return 1;\n }\n\n // Default to basic colors on TTY\n return 1;\n}\n\n/**\n * Options for creating a render context.\n */\nexport interface CreateRenderContextOptions {\n /** Override the detected terminal width */\n width?: number;\n /** Provide a custom theme (default: defaultTheme if colors enabled) */\n theme?: TuiTheme;\n /** Disable colors even if terminal supports them */\n noColor?: boolean;\n /**\n * Explicit render mode override.\n * If set, disables auto-detection.\n */\n renderMode?: RenderMode;\n /**\n * Whether to auto-detect render mode based on environment.\n * When true (default), uses markdown mode in AI assistants.\n * @default true\n */\n autoDetectMode?: boolean;\n}\n\n/**\n * Determine the render mode based on options and environment.\n */\nfunction determineRenderMode(options: CreateRenderContextOptions): RenderMode {\n // Explicit override takes precedence\n if (options.renderMode !== undefined) {\n return options.renderMode;\n }\n\n // If auto-detection is disabled, default to ansi\n if (options.autoDetectMode === false) {\n return \"ansi\";\n }\n\n // Auto-detect: use markdown in AI assistant environments\n if (isRunningInAIAssistant()) {\n return \"markdown\";\n }\n\n return \"ansi\";\n}\n\n/**\n * Create a render context from current terminal state.\n *\n * @param options - Optional overrides for the context\n * @returns A RenderContext ready for component rendering\n *\n * @example\n * ```ts\n * // Auto-detect everything with theme\n * const ctx = createRenderContext();\n *\n * // Force a specific width\n * const ctx = createRenderContext({ width: 120 });\n *\n * // Disable colors\n * const ctx = createRenderContext({ noColor: true });\n *\n * // Force markdown mode\n * const ctx = createRenderContext({ renderMode: \"markdown\" });\n * ```\n */\nexport function createRenderContext(\n options: CreateRenderContextOptions = {}\n): RenderContext {\n const renderMode = determineRenderMode(options);\n const colorLevel = options.noColor ? 0 : detectColorLevel();\n const tty = isTTY();\n\n // Determine theme: only apply in ANSI mode with color support\n const theme =\n colorLevel > 0 && renderMode === \"ansi\"\n ? (options.theme ?? defaultTheme)\n : undefined;\n\n const context: RenderContext = {\n width: options.width ?? getTerminalWidth(),\n isTTY: tty,\n colorLevel,\n renderMode,\n style: createStyleFunctions(renderMode, theme),\n };\n\n // Include theme only if colors are supported and in ANSI mode\n if (theme) {\n context.theme = theme;\n }\n\n return context;\n}\n","import { execSync } from \"node:child_process\";\n\n/**\n * Information about a process in the ancestry chain.\n */\nexport interface ProcessAncestor {\n pid: number;\n command: string;\n}\n\n/**\n * Result of environment detection.\n */\nexport interface EnvironmentDetection {\n /** Whether the environment is likely an AI assistant */\n isAIAssistant: boolean;\n /** Confidence level of the detection */\n confidence: \"high\" | \"medium\" | \"low\";\n /** Name of the detected assistant (if identified) */\n detectedAssistant?: string;\n /** Process tree from current process up to init */\n processTree: ProcessAncestor[];\n}\n\n/**\n * Known AI assistant patterns to look for in process tree.\n */\nconst AI_ASSISTANT_PATTERNS: { pattern: RegExp; name: string }[] = [\n { pattern: /claude-code/i, name: \"claude-code\" },\n { pattern: /claude$/i, name: \"claude\" },\n { pattern: /cursor/i, name: \"cursor\" },\n { pattern: /copilot/i, name: \"copilot\" },\n { pattern: /windsurf/i, name: \"windsurf\" },\n { pattern: /cody/i, name: \"cody\" },\n { pattern: /aider/i, name: \"aider\" },\n { pattern: /continue/i, name: \"continue\" }, // continue.dev\n];\n\n/**\n * Walk up the process tree to find parent processes.\n * Only works on Unix-like systems (macOS, Linux).\n *\n * @returns Array of process ancestors from immediate parent up\n */\nexport function getProcessTree(): ProcessAncestor[] {\n if (process.platform === \"win32\") {\n return []; // Not implemented for Windows\n }\n\n const ancestors: ProcessAncestor[] = [];\n let pid = process.ppid;\n\n // Walk up to 20 levels (should be more than enough)\n for (let i = 0; i < 20 && pid > 1; i++) {\n try {\n const output = execSync(`ps -p ${String(pid)} -o ppid=,comm=`, {\n encoding: \"utf-8\",\n timeout: 1000,\n }).trim();\n const match = /^\\s*(\\d+)\\s+(.+)$/.exec(output);\n if (!match?.[1] || !match[2]) break;\n const ppid = parseInt(match[1], 10);\n const command = match[2];\n ancestors.push({ pid, command });\n pid = ppid;\n } catch {\n break;\n }\n }\n\n return ancestors;\n}\n\n/**\n * Find AI assistant in the process tree.\n *\n * @param processTree - Array of process ancestors\n * @returns Name of detected assistant, or undefined\n */\nfunction findAIAssistantInProcessTree(\n processTree: ProcessAncestor[]\n): string | undefined {\n for (const ancestor of processTree) {\n for (const { pattern, name } of AI_ASSISTANT_PATTERNS) {\n if (pattern.test(ancestor.command)) {\n return name;\n }\n }\n }\n return undefined;\n}\n\n/**\n * Detect the environment and determine if running in an AI assistant.\n *\n * Uses multiple heuristics:\n * - Process tree analysis (most reliable)\n * - TTY detection\n * - Environment variables\n * - Color support level\n *\n * @returns Detection result with confidence\n *\n * @example\n * ```ts\n * const detection = detectEnvironment();\n * if (detection.isAIAssistant) {\n * console.log(`Running in ${detection.detectedAssistant}`);\n * }\n * ```\n */\nexport function detectEnvironment(): EnvironmentDetection {\n const processTree = getProcessTree();\n let aiScore = 0;\n let terminalScore = 0;\n let detectedAssistant: string | undefined;\n\n // Process tree analysis (most reliable)\n detectedAssistant = findAIAssistantInProcessTree(processTree);\n if (detectedAssistant) {\n aiScore += 10;\n }\n\n // TTY checks\n const stdoutIsTTY = process.stdout.isTTY;\n const stdinIsTTY = process.stdin.isTTY;\n\n if (!stdoutIsTTY) {\n aiScore += 2;\n } else {\n terminalScore += 2;\n }\n\n if (!stdinIsTTY) {\n aiScore += 1;\n }\n\n // Known AI assistant env vars\n if (process.env[\"CLAUDE_CODE\"]) {\n aiScore += 5;\n detectedAssistant = detectedAssistant ?? \"claude-code\";\n }\n\n if (process.env[\"CURSOR_TRACE_ID\"] || process.env[\"CURSOR_SESSION\"]) {\n aiScore += 3;\n detectedAssistant = detectedAssistant ?? \"cursor\";\n }\n\n // VSCode integration (could be Copilot or just VSCode terminal)\n if (process.env[\"VSCODE_PID\"] || process.env[\"VSCODE_IPC_HOOK\"]) {\n aiScore += 1;\n }\n\n // Terminal program identification\n const termProgram = process.env[\"TERM_PROGRAM\"];\n if (termProgram) {\n const knownTerminals = [\n \"iTerm.app\",\n \"Apple_Terminal\",\n \"Hyper\",\n \"Alacritty\",\n \"kitty\",\n \"WezTerm\",\n \"Ghostty\",\n ];\n if (knownTerminals.some((t) => termProgram.includes(t))) {\n terminalScore += 2;\n }\n }\n\n // TERM variable\n const term = process.env[\"TERM\"];\n if (term && term !== \"dumb\") {\n terminalScore += 1;\n if (term.includes(\"256color\") || term.includes(\"truecolor\")) {\n terminalScore += 1;\n }\n } else if (term === \"dumb\" || !term) {\n aiScore += 1;\n }\n\n // iTerm specific\n if (process.env[\"ITERM_SESSION_ID\"]) {\n terminalScore += 2;\n }\n\n // Kitty\n if (process.env[\"KITTY_WINDOW_ID\"]) {\n terminalScore += 2;\n }\n\n // CI environment (different from AI but also automated)\n if (process.env[\"CI\"] || process.env[\"GITHUB_ACTIONS\"]) {\n aiScore += 2;\n }\n\n // Calculate result\n const isAIAssistant = aiScore > terminalScore;\n\n let confidence: \"high\" | \"medium\" | \"low\";\n const scoreDiff = Math.abs(aiScore - terminalScore);\n if (scoreDiff >= 4) {\n confidence = \"high\";\n } else if (scoreDiff >= 2) {\n confidence = \"medium\";\n } else {\n confidence = \"low\";\n }\n\n const result: EnvironmentDetection = {\n isAIAssistant,\n confidence,\n processTree,\n };\n\n if (detectedAssistant !== undefined) {\n result.detectedAssistant = detectedAssistant;\n }\n\n return result;\n}\n\n/**\n * Simple check if running in an AI assistant environment.\n *\n * @returns true if likely running in an AI assistant\n *\n * @example\n * ```ts\n * if (isRunningInAIAssistant()) {\n * // Use markdown-friendly output\n * }\n * ```\n */\nexport function isRunningInAIAssistant(): boolean {\n return detectEnvironment().isAIAssistant;\n}\n","/**\n * Markdown rendering utilities for AI assistant-friendly output.\n *\n * These utilities help create output that renders well in environments\n * that strip ANSI escape codes but support markdown rendering.\n */\n\nimport { getStringWidth } from \"./width.js\";\n\n/**\n * Style types for the two-color markdown system.\n * - \"primary\": Plain text (default terminal foreground)\n * - \"secondary\": Inline code (`text`) - typically rendered with tan/yellow background\n */\nexport type MarkdownStyle = \"primary\" | \"secondary\";\n\n/**\n * Default anchor character for line starts.\n * Using β”‚ (U+2502 BOX DRAWINGS LIGHT VERTICAL) as it's visually unobtrusive\n * and prevents leading whitespace collapse in markdown rendering.\n */\nexport const DEFAULT_ANCHOR = \"β”‚\";\n\n/**\n * Wrap text in inline code formatting.\n *\n * Adds a leading space before the opening backtick to compensate for\n * the visual width difference when backticks are rendered as invisible.\n *\n * @param text - Text to wrap\n * @returns Text wrapped in inline code with alignment compensation\n *\n * @example\n * ```ts\n * inlineCode(\"hello\") // Returns \" `hello`\"\n * ```\n */\nexport function inlineCode(text: string): string {\n // Leading space compensates for invisible backtick\n return ` \\`${text}\\``;\n}\n\n/**\n * Add an anchor character to the start of a line.\n *\n * Markdown renderers often collapse leading whitespace. Using an anchor\n * character at the start of each line preserves alignment.\n *\n * @param content - Line content (without the anchor)\n * @param anchor - Anchor character to use (defaults to β”‚)\n * @returns Line with anchor prefix\n *\n * @example\n * ```ts\n * anchorLine(\" Sales β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ\") // \"β”‚ Sales β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ\"\n * ```\n */\nexport function anchorLine(\n content: string,\n anchor: string = DEFAULT_ANCHOR\n): string {\n return `${anchor}${content}`;\n}\n\n/**\n * Apply a markdown style to text.\n *\n * Implements the two-color system for markdown mode:\n * - \"primary\": Returns text unchanged (plain foreground)\n * - \"secondary\": Wraps text in inline code (typically tan/yellow background)\n *\n * @param text - Text to style\n * @param style - Style to apply\n * @returns Styled text\n *\n * @example\n * ```ts\n * applyMarkdownStyle(\"Sales\", \"primary\") // \"Sales\"\n * applyMarkdownStyle(\"Support\", \"secondary\") // \" `Support`\"\n * ```\n */\nexport function applyMarkdownStyle(text: string, style: MarkdownStyle): string {\n if (style === \"secondary\") {\n return inlineCode(text);\n }\n return text;\n}\n\n/**\n * Join multiple lines with anchors.\n *\n * @param lines - Lines to join\n * @param anchor - Anchor character to use\n * @returns Lines joined with newlines, each prefixed with anchor\n *\n * @example\n * ```ts\n * joinAnchoredLines([\"line 1\", \"line 2\"]) // \"β”‚line 1\\nβ”‚line 2\"\n * ```\n */\nexport function joinAnchoredLines(\n lines: string[],\n anchor: string = DEFAULT_ANCHOR\n): string {\n return lines.map((line) => anchorLine(line, anchor)).join(\"\\n\");\n}\n\n/**\n * Strip markdown formatting characters that will be consumed during rendering.\n *\n * This removes:\n * - Inline code backticks: `text` β†’ text\n * - Bold markers: **text** or __text__ β†’ text\n * - Italic markers at word boundaries: *text* or _text_ β†’ text\n *\n * It preserves:\n * - Mid-word underscores: foo_bar stays as foo_bar\n * - Asterisks with surrounding spaces: a * b stays as a * b\n * - Unmatched markers without a closing pair\n *\n * @param str - String potentially containing markdown formatting\n * @returns String with consumed formatting characters removed\n *\n * @example\n * ```ts\n * stripMarkdownFormatting(\"`code`\") // \"code\"\n * stripMarkdownFormatting(\"**bold**\") // \"bold\"\n * stripMarkdownFormatting(\"_italic_\") // \"italic\"\n * stripMarkdownFormatting(\"foo_bar\") // \"foo_bar\" (preserved)\n * stripMarkdownFormatting(\"a * b\") // \"a * b\" (preserved)\n * ```\n */\nexport function stripMarkdownFormatting(str: string): string {\n let result = str;\n\n // Remove inline code backticks (highest priority - prevents other formatting inside)\n // Match `...` where content doesn't contain backticks\n result = result.replace(/`([^`]+)`/g, \"$1\");\n\n // Remove bold markers: **text** or __text__\n result = result.replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\");\n result = result.replace(/__([^_]+)__/g, \"$1\");\n\n // Remove italic markers at word boundaries: *text* or _text_\n // These patterns match markers at start/end of string or with word boundaries\n // *text* - asterisks at word boundaries (not mid-word, not spaced like \"a * b\")\n result = result.replace(\n /(?<![*\\w])\\*([^*\\s][^*]*[^*\\s]|[^*\\s])\\*(?![*\\w])/g,\n \"$1\"\n );\n\n // _text_ - underscores at word boundaries (not mid-word like foo_bar)\n result = result.replace(\n /(?<![_\\w])_([^_\\s][^_]*[^_\\s]|[^_\\s])_(?![_\\w])/g,\n \"$1\"\n );\n\n return result;\n}\n\n/**\n * Get the visual width of a string after markdown rendering.\n *\n * This accounts for markdown formatting characters that will be consumed\n * (become invisible) when rendered, such as backticks for inline code,\n * asterisks for bold/italic, etc.\n *\n * Use this instead of getStringWidth() when calculating alignment for\n * markdown output where formatting characters affect visual width.\n *\n * @param str - String potentially containing markdown formatting\n * @returns Visual width in columns after markdown rendering\n *\n * @example\n * ```ts\n * getStringWidth(\"`code`\") // 6 (counts backticks)\n * getMarkdownRenderedWidth(\"`code`\") // 4 (backticks will be invisible)\n *\n * getStringWidth(\"**bold**\") // 8 (counts asterisks)\n * getMarkdownRenderedWidth(\"**bold**\") // 4 (asterisks will be invisible)\n *\n * getStringWidth(\"foo_bar\") // 7\n * getMarkdownRenderedWidth(\"foo_bar\") // 7 (underscore preserved mid-word)\n * ```\n */\nexport function getMarkdownRenderedWidth(str: string): number {\n return getStringWidth(stripMarkdownFormatting(str));\n}\n","/**\n * Unified semantic styling for TUI components.\n *\n * Provides consistent styling across render modes:\n * - ANSI mode: Uses theme semantic colors\n * - Markdown mode: Uses markdown formatting (backticks, bold, etc.)\n */\n\nimport type { RenderMode } from \"./component.js\";\nimport { inlineCode } from \"./markdown.js\";\nimport type { TuiTheme } from \"./theme.js\";\n\n/**\n * Semantic styling functions that work across render modes.\n *\n * Components call these functions to apply semantic styling:\n * - In ANSI mode: Applies theme colors\n * - In markdown mode: Applies markdown formatting\n *\n * @example\n * ```ts\n * // In a component render method:\n * const styledText = context.style.secondary(sparklineBlocks);\n * // ANSI mode: muted color\n * // Markdown mode: `sparklineBlocks` (backtick wrapped)\n * ```\n */\nexport interface StyleFunctions {\n /** Primary content - default foreground */\n primary: (text: string) => string;\n /** Secondary/muted content - subdued style */\n secondary: (text: string) => string;\n /** Headers and titles - emphasized style */\n header: (text: string) => string;\n /** Borders and separators - subtle style */\n border: (text: string) => string;\n /** Success state - positive indicator */\n success: (text: string) => string;\n /** Warning state - caution indicator */\n warning: (text: string) => string;\n /** Error state - negative indicator */\n error: (text: string) => string;\n /** Informational text - neutral highlight */\n info: (text: string) => string;\n}\n\n/**\n * Style function implementations for markdown mode.\n *\n * Maps semantic styles to markdown formatting:\n * - primary: Plain text (no formatting)\n * - secondary: Inline code backticks (visual distinction via background color)\n * - header: Bold (**text**)\n * - border: Plain text (borders don't need styling in markdown)\n * - success/warning/error/info: Inline code (colored in many renderers)\n */\nconst markdownStyleFunctions: StyleFunctions = {\n primary: (text: string) => text,\n secondary: (text: string) => (text === \"\" ? \"\" : inlineCode(text)),\n header: (text: string) => (text === \"\" ? \"\" : `**${text}**`),\n border: (text: string) => text,\n success: (text: string) => (text === \"\" ? \"\" : inlineCode(text)),\n warning: (text: string) => (text === \"\" ? \"\" : inlineCode(text)),\n error: (text: string) => (text === \"\" ? \"\" : inlineCode(text)),\n info: (text: string) => (text === \"\" ? \"\" : inlineCode(text)),\n};\n\n/**\n * Create passthrough style functions (no styling applied).\n */\nfunction createPassthroughStyleFunctions(): StyleFunctions {\n const passthrough = (text: string) => text;\n return {\n primary: passthrough,\n secondary: passthrough,\n header: passthrough,\n border: passthrough,\n success: passthrough,\n warning: passthrough,\n error: passthrough,\n info: passthrough,\n };\n}\n\n/**\n * Create style functions that apply theme colors.\n */\nfunction createThemedStyleFunctions(theme: TuiTheme): StyleFunctions {\n return {\n primary: (text: string) => theme.semantic.primary(text),\n secondary: (text: string) => theme.semantic.secondary(text),\n header: (text: string) => theme.semantic.header(text),\n border: (text: string) => theme.semantic.border(text),\n success: (text: string) => theme.semantic.success(text),\n warning: (text: string) => theme.semantic.warning(text),\n error: (text: string) => theme.semantic.error(text),\n info: (text: string) => theme.semantic.info(text),\n };\n}\n\n/**\n * Create style functions appropriate for the render mode.\n *\n * @param renderMode - The current render mode (\"ansi\" or \"markdown\")\n * @param theme - Optional theme for ANSI mode styling\n * @returns StyleFunctions that apply mode-appropriate styling\n *\n * @example\n * ```ts\n * // Markdown mode\n * const style = createStyleFunctions(\"markdown\");\n * style.secondary(\"blocks\") // Returns \" `blocks`\"\n *\n * // ANSI mode with theme\n * const style = createStyleFunctions(\"ansi\", theme);\n * style.secondary(\"blocks\") // Returns muted-colored text\n *\n * // ANSI mode without theme\n * const style = createStyleFunctions(\"ansi\");\n * style.secondary(\"blocks\") // Returns \"blocks\" unchanged\n * ```\n */\nexport function createStyleFunctions(\n renderMode: RenderMode,\n theme?: TuiTheme\n): StyleFunctions {\n if (renderMode === \"markdown\") {\n return markdownStyleFunctions;\n }\n\n // ANSI mode: use theme if available, otherwise passthrough\n if (theme) {\n return createThemedStyleFunctions(theme);\n }\n\n return createPassthroughStyleFunctions();\n}\n","import {\n createT1Theme,\n detectTheme as detectChromatermTheme,\n type Theme as ChromatermTheme,\n type Color as ChromatermColor,\n type ThemeOptions,\n} from \"chromaterm\";\n\n// Re-export chromaterm types for consumers\nexport type { ChromatermTheme, ChromatermColor, ThemeOptions };\n\n/**\n * Semantic color mappings for TUI components.\n * Maps component-level semantic names to chromaterm theme colors.\n */\nexport interface SemanticColors {\n /** Primary content color */\n primary: ChromatermColor;\n /** Secondary/muted content */\n secondary: ChromatermColor;\n /** Borders and separators */\n border: ChromatermColor;\n /** Headers and titles */\n header: ChromatermColor;\n /** Success state */\n success: ChromatermColor;\n /** Warning state */\n warning: ChromatermColor;\n /** Error state */\n error: ChromatermColor;\n /** Informational text */\n info: ChromatermColor;\n /** Added content (diffs) */\n added: ChromatermColor;\n /** Removed content (diffs) */\n removed: ChromatermColor;\n /** Modified content (diffs) */\n modified: ChromatermColor;\n}\n\n/**\n * TUI component theme combining chromaterm's theme with semantic mappings.\n */\nexport interface TuiTheme {\n /** Underlying chromaterm theme with ANSI colors */\n chromaterm: ChromatermTheme;\n /** Semantic color mappings for components */\n semantic: SemanticColors;\n}\n\n/**\n * Create semantic color mappings from a chromaterm theme.\n *\n * @param theme - The chromaterm theme\n * @returns Semantic color mappings\n */\nfunction createSemanticColors(theme: ChromatermTheme): SemanticColors {\n return {\n primary: theme.foreground,\n secondary: theme.muted,\n border: theme.muted,\n header: theme.brightWhite,\n success: theme.success,\n warning: theme.warning,\n error: theme.error,\n info: theme.info,\n added: theme.green,\n removed: theme.red,\n modified: theme.yellow,\n };\n}\n\n/**\n * Create a synchronous T1 (ANSI-16) theme.\n * Use this when you need a theme immediately without probing.\n *\n * @returns TUI theme with ANSI-16 colors\n *\n * @example\n * ```ts\n * const theme = createThemeSync();\n * console.log(theme.semantic.error(\"Error message\"));\n * ```\n */\nexport function createThemeSync(): TuiTheme {\n const chromaterm = createT1Theme();\n return {\n chromaterm,\n semantic: createSemanticColors(chromaterm),\n };\n}\n\n/**\n * Detect terminal capabilities and create an optimized theme.\n * Uses OSC probing to detect the terminal's actual color palette.\n *\n * @param options - Theme detection options\n * @returns Promise resolving to TUI theme with detected colors\n *\n * @example\n * ```ts\n * const theme = await detectTheme();\n * console.log(theme.semantic.success(\"Success!\"));\n * ```\n */\nexport async function detectTheme(options?: ThemeOptions): Promise<TuiTheme> {\n const chromaterm = await detectChromatermTheme(options);\n return {\n chromaterm,\n semantic: createSemanticColors(chromaterm),\n };\n}\n\n/**\n * Global default theme instance (T1 baseline).\n * For full capability detection, use `detectTheme()` instead.\n */\nexport const defaultTheme: TuiTheme = createThemeSync();\n","import wrapAnsi from \"wrap-ansi\";\nimport { getStringWidth } from \"./width.js\";\n\n/**\n * Options for text wrapping.\n */\nexport interface WrapOptions {\n /** Whether to hard-wrap words that exceed the width */\n hard?: boolean;\n /** Whether to trim leading/trailing whitespace from each line */\n trim?: boolean;\n /** Whether to wrap at word boundaries (default: true) */\n wordWrap?: boolean;\n}\n\n/**\n * Wrap text to fit within a specified width.\n * Preserves ANSI escape codes when wrapping.\n *\n * @param text - Text to wrap\n * @param width - Maximum width in columns\n * @param options - Wrapping options\n * @returns Wrapped text with newlines\n *\n * @example\n * ```ts\n * wrapText(\"The quick brown fox jumps over the lazy dog\", 20);\n * // \"The quick brown fox\\njumps over the lazy\\ndog\"\n *\n * // With ANSI codes preserved\n * wrapText(\"\\x1b[31mRed text that is very long\\x1b[0m\", 10);\n * // \"\\x1b[31mRed text\\x1b[0m\\n\\x1b[31mthat is\\x1b[0m\\n\\x1b[31mvery long\\x1b[0m\"\n * ```\n */\nexport function wrapText(\n text: string,\n width: number,\n options: WrapOptions = {}\n): string {\n const { hard = false, trim = true, wordWrap = true } = options;\n\n return wrapAnsi(text, width, {\n hard,\n trim,\n wordWrap,\n });\n}\n\n/**\n * Wrap text and return information about the result.\n *\n * @param text - Text to wrap\n * @param width - Maximum width in columns\n * @param options - Wrapping options\n * @returns Object with wrapped text and metadata\n */\nexport function wrapTextWithInfo(\n text: string,\n width: number,\n options: WrapOptions = {}\n): {\n text: string;\n lines: string[];\n lineCount: number;\n maxWidth: number;\n} {\n const wrapped = wrapText(text, width, options);\n const lines = wrapped.split(\"\\n\");\n\n let maxWidth = 0;\n for (const line of lines) {\n const lineWidth = getStringWidth(line);\n if (lineWidth > maxWidth) {\n maxWidth = lineWidth;\n }\n }\n\n return {\n text: wrapped,\n lines,\n lineCount: lines.length,\n maxWidth,\n };\n}\n"],"mappings":"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","names":["stringWidth","detectChromatermTheme","terminalSize","wrapAnsi"]}