{"version":3,"sources":["../src/output/output-impl.ts","../src/output/factory.ts","../src/fs/fs.ts","../src/repo/repo.ts"],"names":["box","sideBorderBox","formatTable","table","keyValue","createSpinner","safeColors","safeSymbols","path","fsp","existsSync","readFileSync","results","readdirSync","statSync"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @module @kb-labs/core-sys/output/output-impl\n * Output implementation\n */\n\nimport type {\n    Output,\n    OutputMode,\n    VerbosityLevel,\n    DebugFormat,\n    OutputLogSink,\n    OutputLogRecord,\n    OutputLogger,\n    ErrorOptions,\n    ProgressDetails,\n    UIUtilities,\n    Spinner,\n} from \"./types.js\";\nimport {\n    box,\n    keyValue,\n    table,\n    createSpinner,\n    safeColors,\n    safeSymbols,\n    sideBorderBox,\n} from \"@kb-labs/shared-cli-ui\";\nimport { formatTable } from \"@kb-labs/shared-cli-ui/table\";\n\nexport class OutputImpl implements Output {\n    constructor(\n        private config: {\n            mode: OutputMode;\n            verbosity: VerbosityLevel;\n            format: DebugFormat;\n            json: boolean;\n            sinks: OutputLogSink[]; // Только для форматированного вывода (ConsoleSink)\n            logger: OutputLogger; // Глобальный logger для записи в файлы\n            category?: string;\n            context?: Record<string, unknown>;\n        }\n    ) {}\n\n    // Getters\n    get mode(): OutputMode {\n        return this.config.mode;\n    }\n\n    get verbosity(): VerbosityLevel {\n        return this.config.verbosity;\n    }\n\n    get isQuiet(): boolean {\n        return this.config.verbosity === \"quiet\";\n    }\n\n    get isVerbose(): boolean {\n        return [\"verbose\", \"debug\", \"inspect\"].includes(this.config.verbosity);\n    }\n\n    get isDebug(): boolean {\n        return [\"debug\", \"inspect\"].includes(this.config.verbosity);\n    }\n\n    get isJSON(): boolean {\n        return this.config.json;\n    }\n\n    get isAIFormat(): boolean {\n        return this.config.format === \"ai\";\n    }\n\n    get ui(): UIUtilities {\n        return {\n            box,\n            sideBox: sideBorderBox,\n            table: (rows, headers) => {\n                if (headers && headers.length > 0) {\n                    return formatTable(\n                        headers.map((h) => ({\n                            header: h,\n                            width: undefined,\n                            align: \"left\" as const,\n                        })),\n                        rows.map((r) => r.map(String)),\n                        { header: true }\n                    );\n                }\n                return table(rows.map((r) => r.map(String)));\n            },\n            keyValue,\n            spinner: (text: string, jsonMode?: boolean) =>\n                createSpinner(text, jsonMode || this.isJSON),\n            colors: {\n                info: safeColors.info,\n                warn: safeColors.warning,\n                error: safeColors.error,\n                success: safeColors.success,\n                muted: safeColors.muted,\n                bold: safeColors.bold,\n                primary: safeColors.primary,\n                accent: safeColors.accent,\n            },\n            symbols: {\n                success: safeSymbols.success,\n                error: safeSymbols.error,\n                warning: safeSymbols.warning,\n                info: safeSymbols.info,\n                bullet: safeSymbols.bullet,\n            },\n        };\n    }\n\n    // Main methods\n    success(message: string, data?: Record<string, unknown>): void {\n        if (this.isJSON) {\n            this.json({ ok: true, message, ...data });\n            return;\n        }\n\n        if (this.isQuiet) {return;}\n\n        const output = `${safeSymbols.success} ${message}`;\n        console.log(safeColors.success(output));\n        // Использовать глобальный logger для записи в файлы\n        this.config.logger.info(message, data);\n    }\n\n    error(error: Error | string, options?: ErrorOptions): void {\n        const message = error instanceof Error ? error.message : error;\n        const stack = error instanceof Error ? error.stack : undefined;\n\n        if (this.isJSON) {\n            this.json({\n                ok: false,\n                error: {\n                    message,\n                    code: options?.code,\n                    context: options?.context,\n                    suggestions: options?.suggestions,\n                },\n            });\n            return;\n        }\n\n        // Красивое форматирование ошибки\n        const lines: string[] = [];\n\n        if (options?.title) {\n            lines.push(\n                safeColors.error(`${safeSymbols.error} ${options.title}`)\n            );\n        }\n\n        lines.push(safeColors.error(message));\n\n        if (options?.code) {\n            lines.push(safeColors.muted(`Code: ${options.code}`));\n        }\n\n        if (options?.context && Object.keys(options.context).length > 0) {\n            lines.push(\"\");\n            lines.push(safeColors.bold(\"Context:\"));\n            lines.push(\n                ...keyValue(\n                    Object.fromEntries(\n                        Object.entries(options.context).map(([k, v]) => [\n                            k,\n                            String(v),\n                        ])\n                    )\n                )\n            );\n        }\n\n        if (options?.suggestions && options.suggestions.length > 0) {\n            lines.push(\"\");\n            lines.push(safeColors.bold(\"Suggestions:\"));\n            options.suggestions.forEach((s) => {\n                lines.push(`  ${safeSymbols.bullet} ${s}`);\n            });\n        }\n\n        if (options?.docs) {\n            lines.push(\"\");\n            lines.push(safeColors.info(`Documentation: ${options.docs}`));\n        }\n\n        const boxed = box(\"Error\", lines);\n        console.error(boxed);\n\n        // Использовать глобальный logger для записи в файлы\n        const errorMeta: Record<string, unknown> = {\n            code: options?.code,\n            context: options?.context,\n        };\n        if (stack) {\n            errorMeta.stack = stack;\n        }\n        if (error instanceof Error) {\n            this.config.logger.error(message, error);\n        } else {\n            this.config.logger.error(message, undefined, errorMeta);\n        }\n    }\n\n    warn(message: string, hint?: string): void {\n        if (this.isQuiet) {return;}\n\n        const output = `${safeSymbols.warning} ${message}`;\n        console.warn(safeColors.warning(output));\n\n        if (hint) {\n            console.warn(safeColors.muted(`  ${hint}`));\n        }\n\n        // Использовать глобальный logger для записи в файлы\n        this.config.logger.warn(message, { hint });\n    }\n\n    progress(stage: string, details?: ProgressDetails): void {\n        if (this.isQuiet) {return;}\n\n        let output = stage;\n        if (details?.current !== undefined && details?.total !== undefined) {\n            const percent = Math.round(\n                (details.current / details.total) * 100\n            );\n            output += ` (${details.current}/${details.total}, ${percent}%)`;\n        }\n\n        if (details?.message) {\n            output += ` - ${details.message}`;\n        }\n\n        console.log(safeColors.info(output));\n        // Использовать глобальный logger для записи в файлы\n        this.config.logger.info(output, details as Record<string, unknown>);\n    }\n\n    spinner(text: string): Spinner {\n        return createSpinner(text, this.isJSON || this.isQuiet);\n    }\n\n    info(message: string, meta?: Record<string, unknown>): void {\n        if (!this.isVerbose) {return;}\n\n        console.log(message);\n        // Использовать глобальный logger для записи в файлы\n        this.config.logger.info(message, meta);\n    }\n\n    debug(message: string, meta?: Record<string, unknown>): void {\n        if (!this.isDebug) {return;}\n\n        console.log(safeColors.muted(message));\n        // Использовать глобальный logger для записи в файлы\n        this.config.logger.debug(message, meta);\n    }\n\n    trace(message: string, meta?: Record<string, unknown>): void {\n        if (this.verbosity !== \"inspect\") {return;}\n\n        console.log(safeColors.muted(`[TRACE] ${message}`));\n        // Использовать глобальный logger для записи в файлы (trace → debug)\n        this.config.logger.debug(message, { ...meta, trace: true } as Record<string, unknown>);\n    }\n\n    json(data: unknown): void {\n        console.log(JSON.stringify(data, null, 2));\n    }\n\n    write(text: string): void {\n        if (this.isQuiet) {return;}\n        console.log(text);\n    }\n\n    group(name: string): void {\n        if (this.isDebug) {\n            console.group(name);\n        }\n    }\n\n    groupEnd(): void {\n        if (this.isDebug) {\n            console.groupEnd();\n        }\n    }\n\n    // Internal method для форматированного вывода через ConsoleSink\n    // Используется только для UI вывода, не для записи в файлы\n    private logToConsoleSink(\n        level: OutputLogRecord[\"level\"],\n        msg: string,\n        meta?: Record<string, unknown>\n    ): void {\n        const record: OutputLogRecord = {\n            time: new Date().toISOString(),\n            ts: new Date().toISOString(),\n            level,\n            category: this.config.category,\n            msg,\n            meta: { ...this.config.context, ...meta },\n        };\n\n        // Отправить только в ConsoleSink для форматированного вывода\n        // Запись в файлы идет через глобальный logger\n        for (const sink of this.config.sinks) {\n            try {\n                void sink.handle(record);\n            } catch (err) {\n                // Sink failures should not break execution\n                console.error(\"Sink error:\", err);\n            }\n        }\n    }\n}\n","/**\n * @module @kb-labs/core-sys/output/factory\n * Output factory with auto-detection\n */\n\nimport type { Output, OutputMode, VerbosityLevel, DebugFormat, OutputLogSink, OutputLogger } from \"./types.js\";\nimport { OutputImpl } from \"./output-impl.js\";\n\ntype LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\nclass ConsoleLogger implements OutputLogger {\n    constructor(\n        private readonly level: LogLevel,\n        private readonly bindings: Record<string, unknown> = {}\n    ) {}\n\n    private canLog(target: LogLevel): boolean {\n        const rank: Record<LogLevel, number> = {\n            silent: 0,\n            error: 1,\n            warn: 2,\n            info: 3,\n            debug: 4,\n            trace: 5,\n        };\n        return rank[target] <= rank[this.level];\n    }\n\n    private withMeta(meta?: Record<string, unknown>): string {\n        const merged = { ...this.bindings, ...(meta ?? {}) };\n        return Object.keys(merged).length > 0 ? ` ${JSON.stringify(merged)}` : \"\";\n    }\n\n    info(message: string, meta?: Record<string, unknown>): void {\n        if (this.canLog(\"info\")) {\n            console.log(`[INFO] ${message}${this.withMeta(meta)}`);\n        }\n    }\n\n    warn(message: string, meta?: Record<string, unknown>): void {\n        if (this.canLog(\"warn\")) {\n            console.warn(`[WARN] ${message}${this.withMeta(meta)}`);\n        }\n    }\n\n    error(message: string, error?: Error, meta?: Record<string, unknown>): void {\n        if (this.canLog(\"error\")) {\n            const payload = error\n                ? { ...meta, error: { message: error.message, stack: error.stack } }\n                : meta;\n            console.error(`[ERROR] ${message}${this.withMeta(payload)}`);\n        }\n    }\n\n    debug(message: string, meta?: Record<string, unknown>): void {\n        if (this.canLog(\"debug\")) {\n            console.debug(`[DEBUG] ${message}${this.withMeta(meta)}`);\n        }\n    }\n\n    child(bindings: Record<string, unknown>): OutputLogger {\n        return new ConsoleLogger(this.level, { ...this.bindings, ...bindings });\n    }\n}\n\nexport interface OutputConfig {\n    verbosity?: VerbosityLevel; // Из флагов\n    mode?: OutputMode; // Auto-detect или explicit\n    format?: DebugFormat; // 'human' | 'ai'\n    json?: boolean; // --json флаг\n    sinks?: OutputLogSink[]; // Дополнительные sinks\n    category?: string; // Категория для логов\n    context?: {\n        // Контекст команды\n        plugin?: string;\n        command?: string;\n        trace?: string;\n    };\n}\n\nexport function createOutput(config: OutputConfig = {}): Output {\n    // Auto-detect mode\n    const mode: OutputMode = config.mode || detectMode();\n\n    // Verbosity из конфига или normal по умолчанию\n    const verbosity: VerbosityLevel = config.verbosity || \"normal\";\n\n    // Format\n    const format: DebugFormat =\n        config.format || (config.json ? \"ai\" : \"human\");\n\n    // Создать sinks только для форматированного вывода пользователю\n    const sinks: OutputLogSink[] = config.sinks || [];\n\n    const loggerLevel =\n        verbosity === \"inspect\"\n            ? \"trace\"\n            : verbosity === \"debug\"\n              ? \"debug\"\n              : verbosity === \"verbose\"\n                ? \"info\"\n                : verbosity === \"quiet\"\n                  ? \"silent\"\n                  : \"info\";\n    const logger = new ConsoleLogger(loggerLevel, {\n        category: config.category || \"output\",\n        ...(config.context || {}),\n    });\n\n    // Создать Output implementation\n    return new OutputImpl({\n        mode,\n        verbosity,\n        format,\n        json: config.json || false,\n        sinks, // Только ConsoleSink для UI\n        logger, // Глобальный logger для записи в файлы\n        category: config.category,\n        context: config.context,\n    });\n}\n\nfunction detectMode(): OutputMode {\n    // CI environment\n    if (process.env.CI === \"true\") {\n        return \"ci\";\n    }\n\n    // TTY\n    if (process.stdout.isTTY) {\n        return \"tty\";\n    }\n\n    // Pipe\n    return \"pipe\";\n}\n","/**\n * @module @kb-labs/core/sys/fs\n * Safe path helpers with explicit bases.\n */\n\nimport path from \"node:path\";\n\nexport function toAbsolute(baseDir: string, maybeRelative?: string): string {\n    if (!maybeRelative) { return baseDir; }\n    return path.isAbsolute(maybeRelative) ? maybeRelative : path.join(baseDir, maybeRelative);\n}","/**\n * @module @kb-labs/core/sys/repo\n * Repository root discovery. Pure infrastructure, no domain keys.\n */\n\nimport path from \"node:path\";\nimport { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { promises as fsp } from \"node:fs\";\nimport type { SubRepo } from '../types/index.js';\n\n/**\n * Find repository root by searching for markers in priority order.\n * First searches entire tree for pnpm-workspace.yaml (monorepo root),\n * then .git, then package.json as fallback.\n */\nexport async function findRepoRoot(startDir = process.cwd()): Promise<string> {\n    const markersPriority = [\"pnpm-workspace.yaml\", \".git\", \"package.json\"];\n\n    // Try each marker in priority order, searching entire tree each time\n    for (const marker of markersPriority) {\n        let dir = path.resolve(startDir);\n        while (true) {\n            try {\n                await fsp.access(path.join(dir, marker));\n                return dir; // Found it!\n            } catch {\n                // Continue searching upward\n            }\n\n            const parent = path.dirname(dir);\n            if (parent === dir) {\n                // Reached filesystem root without finding this marker\n                break;\n            }\n            dir = parent;\n        }\n    }\n\n    // Fallback: return current directory if nothing found\n    return path.resolve(startDir);\n}\n\n/**\n * Discover all sub-repository absolute paths in a monorepo root.\n *\n * Reads paths from `.gitmodules` — no hardcoded category directories.\n * Falls back to scanning top-level dirs for `.git` (flat layout).\n *\n * @returns Absolute paths to each sub-repo that exists on disk.\n */\nexport function discoverSubRepoPaths(repoRoot: string): string[] {\n  const gitmodulesPath = path.join(repoRoot, '.gitmodules');\n\n  if (existsSync(gitmodulesPath)) {\n    try {\n      const content = readFileSync(gitmodulesPath, 'utf-8');\n      const results: string[] = [];\n      for (const match of content.matchAll(/^\\s*path\\s*=\\s*(.+)$/gm)) {\n        const relPath = (match[1] ?? '').trim();\n        if (!relPath) { continue; }\n        const fullPath = path.join(repoRoot, relPath);\n        if (existsSync(fullPath)) { results.push(fullPath); }\n      }\n      if (results.length > 0) { return results; }\n    } catch {\n      // fall through to filesystem scan\n    }\n  }\n\n  // Fallback: flat layout — top-level dirs with .git\n  const results: string[] = [];\n  try {\n    for (const entry of readdirSync(repoRoot)) {\n      if (entry.startsWith('.') || entry === 'node_modules') { continue; }\n      const fullPath = path.join(repoRoot, entry);\n      try {\n        if (statSync(fullPath).isDirectory() && existsSync(path.join(fullPath, '.git'))) {\n          results.push(fullPath);\n        }\n      } catch { /* skip */ }\n    }\n  } catch { /* skip */ }\n  return results;\n}\n\n/**\n * Like discoverSubRepoPaths but returns structured SubRepo objects\n * with path, category, name, and absolutePath fields.\n */\nexport function discoverSubRepos(repoRoot: string): SubRepo[] {\n  const gitmodulesPath = path.join(repoRoot, '.gitmodules');\n\n  if (existsSync(gitmodulesPath)) {\n    try {\n      const content = readFileSync(gitmodulesPath, 'utf-8');\n      const results: SubRepo[] = [];\n      for (const match of content.matchAll(/^\\s*path\\s*=\\s*(.+)$/gm)) {\n        const relPath = (match[1] ?? '').trim();\n        if (!relPath) { continue; }\n        const absolutePath = path.join(repoRoot, relPath);\n        if (!existsSync(absolutePath)) { continue; }\n        const parts = relPath.split('/');\n        const name = parts.at(-1) ?? relPath;\n        const category = parts.length > 1 ? parts.slice(0, -1).join('/') : '';\n        results.push({ path: relPath, category, name, absolutePath });\n      }\n      if (results.length > 0) { return results; }\n    } catch { /* fall through */ }\n  }\n\n  // Fallback: flat layout — top-level dirs with .git\n  const results: SubRepo[] = [];\n  try {\n    for (const entry of readdirSync(repoRoot)) {\n      if (entry.startsWith('.') || entry === 'node_modules') { continue; }\n      const absolutePath = path.join(repoRoot, entry);\n      try {\n        if (statSync(absolutePath).isDirectory() &&\n            existsSync(path.join(absolutePath, '.git'))) {\n          results.push({ path: entry, category: '', name: entry, absolutePath });\n        }\n      } catch { /* skip */ }\n    }\n  } catch { /* skip */ }\n  return results;\n}"]}