@kb-labs/core-sys 1.0.0 → 1.3.0
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.
- package/README.md +3 -1
- package/dist/index.cjs +86 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +86 -2
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ pnpm add @kb-labs/core-sys
|
|
|
60
60
|
```typescript
|
|
61
61
|
import { createOutput } from '@kb-labs/core-sys/output';
|
|
62
62
|
import { toAbsolute } from '@kb-labs/core-sys/fs';
|
|
63
|
-
import { findRepoRoot } from '@kb-labs/core-sys/repo';
|
|
63
|
+
import { findRepoRoot, discoverSubRepos } from '@kb-labs/core-sys/repo';
|
|
64
64
|
|
|
65
65
|
// Output
|
|
66
66
|
const out = createOutput({ verbosity: 'normal' });
|
|
@@ -71,6 +71,7 @@ const absPath = toAbsolute('/base', './relative');
|
|
|
71
71
|
|
|
72
72
|
// Repository
|
|
73
73
|
const repoRoot = await findRepoRoot();
|
|
74
|
+
const subRepos = discoverSubRepos(repoRoot); // [{ path, category, name, absolutePath }]
|
|
74
75
|
```
|
|
75
76
|
|
|
76
77
|
## ✨ Features
|
|
@@ -89,6 +90,7 @@ const repoRoot = await findRepoRoot();
|
|
|
89
90
|
### Repository
|
|
90
91
|
|
|
91
92
|
- **Repository Detection**: Find Git repository root
|
|
93
|
+
- **Sub-repository Discovery**: Find all sub-repos with structured `path`, `category`, `name`, and `absolutePath` metadata
|
|
92
94
|
|
|
93
95
|
## 🔧 Configuration
|
|
94
96
|
|
package/dist/index.cjs
CHANGED
|
@@ -348,8 +348,94 @@ async function findRepoRoot(startDir = process.cwd()) {
|
|
|
348
348
|
}
|
|
349
349
|
return path2__default.default.resolve(startDir);
|
|
350
350
|
}
|
|
351
|
+
function discoverSubRepoPaths(repoRoot) {
|
|
352
|
+
const gitmodulesPath = path2__default.default.join(repoRoot, ".gitmodules");
|
|
353
|
+
if (fs.existsSync(gitmodulesPath)) {
|
|
354
|
+
try {
|
|
355
|
+
const content = fs.readFileSync(gitmodulesPath, "utf-8");
|
|
356
|
+
const results2 = [];
|
|
357
|
+
for (const match of content.matchAll(/^\s*path\s*=\s*(.+)$/gm)) {
|
|
358
|
+
const relPath = (match[1] ?? "").trim();
|
|
359
|
+
if (!relPath) {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const fullPath = path2__default.default.join(repoRoot, relPath);
|
|
363
|
+
if (fs.existsSync(fullPath)) {
|
|
364
|
+
results2.push(fullPath);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (results2.length > 0) {
|
|
368
|
+
return results2;
|
|
369
|
+
}
|
|
370
|
+
} catch {
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
const results = [];
|
|
374
|
+
try {
|
|
375
|
+
for (const entry of fs.readdirSync(repoRoot)) {
|
|
376
|
+
if (entry.startsWith(".") || entry === "node_modules") {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
const fullPath = path2__default.default.join(repoRoot, entry);
|
|
380
|
+
try {
|
|
381
|
+
if (fs.statSync(fullPath).isDirectory() && fs.existsSync(path2__default.default.join(fullPath, ".git"))) {
|
|
382
|
+
results.push(fullPath);
|
|
383
|
+
}
|
|
384
|
+
} catch {
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
} catch {
|
|
388
|
+
}
|
|
389
|
+
return results;
|
|
390
|
+
}
|
|
391
|
+
function discoverSubRepos(repoRoot) {
|
|
392
|
+
const gitmodulesPath = path2__default.default.join(repoRoot, ".gitmodules");
|
|
393
|
+
if (fs.existsSync(gitmodulesPath)) {
|
|
394
|
+
try {
|
|
395
|
+
const content = fs.readFileSync(gitmodulesPath, "utf-8");
|
|
396
|
+
const results2 = [];
|
|
397
|
+
for (const match of content.matchAll(/^\s*path\s*=\s*(.+)$/gm)) {
|
|
398
|
+
const relPath = (match[1] ?? "").trim();
|
|
399
|
+
if (!relPath) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
const absolutePath = path2__default.default.join(repoRoot, relPath);
|
|
403
|
+
if (!fs.existsSync(absolutePath)) {
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
const parts = relPath.split("/");
|
|
407
|
+
const name = parts.at(-1) ?? relPath;
|
|
408
|
+
const category = parts.length > 1 ? parts.slice(0, -1).join("/") : "";
|
|
409
|
+
results2.push({ path: relPath, category, name, absolutePath });
|
|
410
|
+
}
|
|
411
|
+
if (results2.length > 0) {
|
|
412
|
+
return results2;
|
|
413
|
+
}
|
|
414
|
+
} catch {
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
const results = [];
|
|
418
|
+
try {
|
|
419
|
+
for (const entry of fs.readdirSync(repoRoot)) {
|
|
420
|
+
if (entry.startsWith(".") || entry === "node_modules") {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
const absolutePath = path2__default.default.join(repoRoot, entry);
|
|
424
|
+
try {
|
|
425
|
+
if (fs.statSync(absolutePath).isDirectory() && fs.existsSync(path2__default.default.join(absolutePath, ".git"))) {
|
|
426
|
+
results.push({ path: entry, category: "", name: entry, absolutePath });
|
|
427
|
+
}
|
|
428
|
+
} catch {
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
} catch {
|
|
432
|
+
}
|
|
433
|
+
return results;
|
|
434
|
+
}
|
|
351
435
|
|
|
352
436
|
exports.createOutput = createOutput;
|
|
437
|
+
exports.discoverSubRepoPaths = discoverSubRepoPaths;
|
|
438
|
+
exports.discoverSubRepos = discoverSubRepos;
|
|
353
439
|
exports.findRepoRoot = findRepoRoot;
|
|
354
440
|
exports.toAbsolute = toAbsolute;
|
|
355
441
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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"],"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\";\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\";\nimport { OutputImpl } from \"./output-impl\";\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 { promises as fsp } from \"node:fs\";\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}"]}
|
|
1
|
+
{"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}"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -3,6 +3,16 @@ interface FindNearestConfigOpts {
|
|
|
3
3
|
stopDir?: string;
|
|
4
4
|
filenames: string[];
|
|
5
5
|
}
|
|
6
|
+
interface SubRepo {
|
|
7
|
+
/** Relative path from repoRoot, e.g. "platform/kb-labs-core" */
|
|
8
|
+
path: string;
|
|
9
|
+
/** Parent segment(s) — e.g. "platform"; empty string for flat layout */
|
|
10
|
+
category: string;
|
|
11
|
+
/** Final directory name — e.g. "kb-labs-core" */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Absolute path on disk — convenience; equals path.join(repoRoot, path) */
|
|
14
|
+
absolutePath: string;
|
|
15
|
+
}
|
|
6
16
|
|
|
7
17
|
/**
|
|
8
18
|
* @module @kb-labs/core-sys/output/types
|
|
@@ -156,11 +166,26 @@ declare function toAbsolute(baseDir: string, maybeRelative?: string): string;
|
|
|
156
166
|
* @module @kb-labs/core/sys/repo
|
|
157
167
|
* Repository root discovery. Pure infrastructure, no domain keys.
|
|
158
168
|
*/
|
|
169
|
+
|
|
159
170
|
/**
|
|
160
171
|
* Find repository root by searching for markers in priority order.
|
|
161
172
|
* First searches entire tree for pnpm-workspace.yaml (monorepo root),
|
|
162
173
|
* then .git, then package.json as fallback.
|
|
163
174
|
*/
|
|
164
175
|
declare function findRepoRoot(startDir?: string): Promise<string>;
|
|
176
|
+
/**
|
|
177
|
+
* Discover all sub-repository absolute paths in a monorepo root.
|
|
178
|
+
*
|
|
179
|
+
* Reads paths from `.gitmodules` — no hardcoded category directories.
|
|
180
|
+
* Falls back to scanning top-level dirs for `.git` (flat layout).
|
|
181
|
+
*
|
|
182
|
+
* @returns Absolute paths to each sub-repo that exists on disk.
|
|
183
|
+
*/
|
|
184
|
+
declare function discoverSubRepoPaths(repoRoot: string): string[];
|
|
185
|
+
/**
|
|
186
|
+
* Like discoverSubRepoPaths but returns structured SubRepo objects
|
|
187
|
+
* with path, category, name, and absolutePath fields.
|
|
188
|
+
*/
|
|
189
|
+
declare function discoverSubRepos(repoRoot: string): SubRepo[];
|
|
165
190
|
|
|
166
|
-
export { type DebugFormat, type ErrorOptions, type FindNearestConfigOpts, type Output, type OutputConfig, type OutputLogLevel, type OutputLogRecord, type OutputLogSink, type OutputLogger, type OutputMode, type ProgressDetails, type Spinner, type UIUtilities, type VerbosityLevel, createOutput, findRepoRoot, toAbsolute };
|
|
191
|
+
export { type DebugFormat, type ErrorOptions, type FindNearestConfigOpts, type Output, type OutputConfig, type OutputLogLevel, type OutputLogRecord, type OutputLogSink, type OutputLogger, type OutputMode, type ProgressDetails, type Spinner, type SubRepo, type UIUtilities, type VerbosityLevel, createOutput, discoverSubRepoPaths, discoverSubRepos, findRepoRoot, toAbsolute };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,16 @@ interface FindNearestConfigOpts {
|
|
|
3
3
|
stopDir?: string;
|
|
4
4
|
filenames: string[];
|
|
5
5
|
}
|
|
6
|
+
interface SubRepo {
|
|
7
|
+
/** Relative path from repoRoot, e.g. "platform/kb-labs-core" */
|
|
8
|
+
path: string;
|
|
9
|
+
/** Parent segment(s) — e.g. "platform"; empty string for flat layout */
|
|
10
|
+
category: string;
|
|
11
|
+
/** Final directory name — e.g. "kb-labs-core" */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Absolute path on disk — convenience; equals path.join(repoRoot, path) */
|
|
14
|
+
absolutePath: string;
|
|
15
|
+
}
|
|
6
16
|
|
|
7
17
|
/**
|
|
8
18
|
* @module @kb-labs/core-sys/output/types
|
|
@@ -156,11 +166,26 @@ declare function toAbsolute(baseDir: string, maybeRelative?: string): string;
|
|
|
156
166
|
* @module @kb-labs/core/sys/repo
|
|
157
167
|
* Repository root discovery. Pure infrastructure, no domain keys.
|
|
158
168
|
*/
|
|
169
|
+
|
|
159
170
|
/**
|
|
160
171
|
* Find repository root by searching for markers in priority order.
|
|
161
172
|
* First searches entire tree for pnpm-workspace.yaml (monorepo root),
|
|
162
173
|
* then .git, then package.json as fallback.
|
|
163
174
|
*/
|
|
164
175
|
declare function findRepoRoot(startDir?: string): Promise<string>;
|
|
176
|
+
/**
|
|
177
|
+
* Discover all sub-repository absolute paths in a monorepo root.
|
|
178
|
+
*
|
|
179
|
+
* Reads paths from `.gitmodules` — no hardcoded category directories.
|
|
180
|
+
* Falls back to scanning top-level dirs for `.git` (flat layout).
|
|
181
|
+
*
|
|
182
|
+
* @returns Absolute paths to each sub-repo that exists on disk.
|
|
183
|
+
*/
|
|
184
|
+
declare function discoverSubRepoPaths(repoRoot: string): string[];
|
|
185
|
+
/**
|
|
186
|
+
* Like discoverSubRepoPaths but returns structured SubRepo objects
|
|
187
|
+
* with path, category, name, and absolutePath fields.
|
|
188
|
+
*/
|
|
189
|
+
declare function discoverSubRepos(repoRoot: string): SubRepo[];
|
|
165
190
|
|
|
166
|
-
export { type DebugFormat, type ErrorOptions, type FindNearestConfigOpts, type Output, type OutputConfig, type OutputLogLevel, type OutputLogRecord, type OutputLogSink, type OutputLogger, type OutputMode, type ProgressDetails, type Spinner, type UIUtilities, type VerbosityLevel, createOutput, findRepoRoot, toAbsolute };
|
|
191
|
+
export { type DebugFormat, type ErrorOptions, type FindNearestConfigOpts, type Output, type OutputConfig, type OutputLogLevel, type OutputLogRecord, type OutputLogSink, type OutputLogger, type OutputMode, type ProgressDetails, type Spinner, type SubRepo, type UIUtilities, type VerbosityLevel, createOutput, discoverSubRepoPaths, discoverSubRepos, findRepoRoot, toAbsolute };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { safeSymbols, safeColors, createSpinner, keyValue, sideBorderBox, box, table } from '@kb-labs/shared-cli-ui';
|
|
2
2
|
import { formatTable } from '@kb-labs/shared-cli-ui/table';
|
|
3
3
|
import path2 from 'path';
|
|
4
|
-
import { promises } from 'fs';
|
|
4
|
+
import { promises, existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
5
5
|
|
|
6
6
|
// src/output/output-impl.ts
|
|
7
7
|
var OutputImpl = class {
|
|
@@ -342,7 +342,91 @@ async function findRepoRoot(startDir = process.cwd()) {
|
|
|
342
342
|
}
|
|
343
343
|
return path2.resolve(startDir);
|
|
344
344
|
}
|
|
345
|
+
function discoverSubRepoPaths(repoRoot) {
|
|
346
|
+
const gitmodulesPath = path2.join(repoRoot, ".gitmodules");
|
|
347
|
+
if (existsSync(gitmodulesPath)) {
|
|
348
|
+
try {
|
|
349
|
+
const content = readFileSync(gitmodulesPath, "utf-8");
|
|
350
|
+
const results2 = [];
|
|
351
|
+
for (const match of content.matchAll(/^\s*path\s*=\s*(.+)$/gm)) {
|
|
352
|
+
const relPath = (match[1] ?? "").trim();
|
|
353
|
+
if (!relPath) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const fullPath = path2.join(repoRoot, relPath);
|
|
357
|
+
if (existsSync(fullPath)) {
|
|
358
|
+
results2.push(fullPath);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (results2.length > 0) {
|
|
362
|
+
return results2;
|
|
363
|
+
}
|
|
364
|
+
} catch {
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const results = [];
|
|
368
|
+
try {
|
|
369
|
+
for (const entry of readdirSync(repoRoot)) {
|
|
370
|
+
if (entry.startsWith(".") || entry === "node_modules") {
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
const fullPath = path2.join(repoRoot, entry);
|
|
374
|
+
try {
|
|
375
|
+
if (statSync(fullPath).isDirectory() && existsSync(path2.join(fullPath, ".git"))) {
|
|
376
|
+
results.push(fullPath);
|
|
377
|
+
}
|
|
378
|
+
} catch {
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
} catch {
|
|
382
|
+
}
|
|
383
|
+
return results;
|
|
384
|
+
}
|
|
385
|
+
function discoverSubRepos(repoRoot) {
|
|
386
|
+
const gitmodulesPath = path2.join(repoRoot, ".gitmodules");
|
|
387
|
+
if (existsSync(gitmodulesPath)) {
|
|
388
|
+
try {
|
|
389
|
+
const content = readFileSync(gitmodulesPath, "utf-8");
|
|
390
|
+
const results2 = [];
|
|
391
|
+
for (const match of content.matchAll(/^\s*path\s*=\s*(.+)$/gm)) {
|
|
392
|
+
const relPath = (match[1] ?? "").trim();
|
|
393
|
+
if (!relPath) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const absolutePath = path2.join(repoRoot, relPath);
|
|
397
|
+
if (!existsSync(absolutePath)) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
const parts = relPath.split("/");
|
|
401
|
+
const name = parts.at(-1) ?? relPath;
|
|
402
|
+
const category = parts.length > 1 ? parts.slice(0, -1).join("/") : "";
|
|
403
|
+
results2.push({ path: relPath, category, name, absolutePath });
|
|
404
|
+
}
|
|
405
|
+
if (results2.length > 0) {
|
|
406
|
+
return results2;
|
|
407
|
+
}
|
|
408
|
+
} catch {
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
const results = [];
|
|
412
|
+
try {
|
|
413
|
+
for (const entry of readdirSync(repoRoot)) {
|
|
414
|
+
if (entry.startsWith(".") || entry === "node_modules") {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
const absolutePath = path2.join(repoRoot, entry);
|
|
418
|
+
try {
|
|
419
|
+
if (statSync(absolutePath).isDirectory() && existsSync(path2.join(absolutePath, ".git"))) {
|
|
420
|
+
results.push({ path: entry, category: "", name: entry, absolutePath });
|
|
421
|
+
}
|
|
422
|
+
} catch {
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
return results;
|
|
428
|
+
}
|
|
345
429
|
|
|
346
|
-
export { createOutput, findRepoRoot, toAbsolute };
|
|
430
|
+
export { createOutput, discoverSubRepoPaths, discoverSubRepos, findRepoRoot, toAbsolute };
|
|
347
431
|
//# sourceMappingURL=index.js.map
|
|
348
432
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/output/output-impl.ts","../src/output/factory.ts","../src/fs/fs.ts","../src/repo/repo.ts"],"names":["path","fsp"],"mappings":"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","file":"index.js","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\";\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\";\nimport { OutputImpl } from \"./output-impl\";\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 { promises as fsp } from \"node:fs\";\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}"]}
|
|
1
|
+
{"version":3,"sources":["../src/output/output-impl.ts","../src/output/factory.ts","../src/fs/fs.ts","../src/repo/repo.ts"],"names":["path","fsp","results"],"mappings":"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","file":"index.js","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}"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/core-sys",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Core system utilities for KB Labs, including file system operations and path resolution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -23,8 +23,18 @@
|
|
|
23
23
|
"LICENSE"
|
|
24
24
|
],
|
|
25
25
|
"sideEffects": false,
|
|
26
|
+
"scripts": {
|
|
27
|
+
"clean": "rimraf dist",
|
|
28
|
+
"build": "pnpm clean && tsup --config tsup.config.ts",
|
|
29
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
30
|
+
"type-check": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run --passWithNoTests",
|
|
32
|
+
"lint": "eslint . --ignore-pattern 'dist/**' --ignore-pattern 'coverage/**' --ignore-pattern 'tsup.config.bundled_*.mjs'",
|
|
33
|
+
"lint:fix": "eslint . --fix --ignore-pattern 'dist/**' --ignore-pattern 'coverage/**' --ignore-pattern 'tsup.config.bundled_*.mjs'",
|
|
34
|
+
"test:watch": "vitest"
|
|
35
|
+
},
|
|
26
36
|
"dependencies": {
|
|
27
|
-
"@kb-labs/shared-cli-ui": "
|
|
37
|
+
"@kb-labs/shared-cli-ui": "^1.0.0"
|
|
28
38
|
},
|
|
29
39
|
"devDependencies": {
|
|
30
40
|
"@types/node": "^24.3.3",
|
|
@@ -33,7 +43,7 @@
|
|
|
33
43
|
"tsup": "^8.5.0",
|
|
34
44
|
"typescript": "^5.6.3",
|
|
35
45
|
"vitest": "^3.2.4",
|
|
36
|
-
"@kb-labs/devkit": "link
|
|
46
|
+
"@kb-labs/devkit": "link:../../../../infra/kb-labs-devkit"
|
|
37
47
|
},
|
|
38
48
|
"module": "./dist/index.js",
|
|
39
49
|
"engines": {
|
|
@@ -42,15 +52,5 @@
|
|
|
42
52
|
},
|
|
43
53
|
"publishConfig": {
|
|
44
54
|
"access": "public"
|
|
45
|
-
},
|
|
46
|
-
"scripts": {
|
|
47
|
-
"clean": "rimraf dist",
|
|
48
|
-
"build": "pnpm clean && tsup --config tsup.config.ts",
|
|
49
|
-
"dev": "tsup --config tsup.config.ts --watch",
|
|
50
|
-
"type-check": "tsc --noEmit",
|
|
51
|
-
"test": "vitest run --passWithNoTests",
|
|
52
|
-
"lint": "eslint . --ignore-pattern 'dist/**' --ignore-pattern 'coverage/**'",
|
|
53
|
-
"lint:fix": "eslint . --fix --ignore-pattern 'dist/**' --ignore-pattern 'coverage/**'",
|
|
54
|
-
"test:watch": "vitest"
|
|
55
55
|
}
|
|
56
|
-
}
|
|
56
|
+
}
|