eff-u-code 2.0.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/LICENSE +21 -0
- package/README.md +256 -0
- package/bin/fuck-u-code-mcp.js +2 -0
- package/bin/fuck-u-code.js +2 -0
- package/bin/postinstall.js +53 -0
- package/dist/ai/index.d.ts +34 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +227 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts/code-review.d.ts +9 -0
- package/dist/ai/prompts/code-review.d.ts.map +1 -0
- package/dist/ai/prompts/code-review.js +61 -0
- package/dist/ai/prompts/code-review.js.map +1 -0
- package/dist/ai/providers/anthropic.d.ts +11 -0
- package/dist/ai/providers/anthropic.d.ts.map +1 -0
- package/dist/ai/providers/anthropic.js +60 -0
- package/dist/ai/providers/anthropic.js.map +1 -0
- package/dist/ai/providers/fetch.d.ts +10 -0
- package/dist/ai/providers/fetch.d.ts.map +1 -0
- package/dist/ai/providers/fetch.js +50 -0
- package/dist/ai/providers/fetch.js.map +1 -0
- package/dist/ai/providers/gemini.d.ts +12 -0
- package/dist/ai/providers/gemini.d.ts.map +1 -0
- package/dist/ai/providers/gemini.js +66 -0
- package/dist/ai/providers/gemini.js.map +1 -0
- package/dist/ai/providers/ollama.d.ts +11 -0
- package/dist/ai/providers/ollama.d.ts.map +1 -0
- package/dist/ai/providers/ollama.js +54 -0
- package/dist/ai/providers/ollama.js.map +1 -0
- package/dist/ai/providers/openai.d.ts +11 -0
- package/dist/ai/providers/openai.d.ts.map +1 -0
- package/dist/ai/providers/openai.js +52 -0
- package/dist/ai/providers/openai.js.map +1 -0
- package/dist/ai/selector.d.ts +19 -0
- package/dist/ai/selector.d.ts.map +1 -0
- package/dist/ai/selector.js +145 -0
- package/dist/ai/selector.js.map +1 -0
- package/dist/ai/types.d.ts +120 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +6 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/analyzer/concurrent-analyzer.d.ts +11 -0
- package/dist/analyzer/concurrent-analyzer.d.ts.map +1 -0
- package/dist/analyzer/concurrent-analyzer.js +67 -0
- package/dist/analyzer/concurrent-analyzer.js.map +1 -0
- package/dist/analyzer/file-discovery.d.ts +23 -0
- package/dist/analyzer/file-discovery.d.ts.map +1 -0
- package/dist/analyzer/file-discovery.js +64 -0
- package/dist/analyzer/file-discovery.js.map +1 -0
- package/dist/analyzer/index.d.ts +27 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +64 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/cli/commands/ai-review.d.ts +6 -0
- package/dist/cli/commands/ai-review.d.ts.map +1 -0
- package/dist/cli/commands/ai-review.js +213 -0
- package/dist/cli/commands/ai-review.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +6 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +145 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/config.d.ts +6 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +147 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/mcp-install.d.ts +9 -0
- package/dist/cli/commands/mcp-install.d.ts.map +1 -0
- package/dist/cli/commands/mcp-install.js +102 -0
- package/dist/cli/commands/mcp-install.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +69 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output/ai-review-output.d.ts +20 -0
- package/dist/cli/output/ai-review-output.d.ts.map +1 -0
- package/dist/cli/output/ai-review-output.js +324 -0
- package/dist/cli/output/ai-review-output.js.map +1 -0
- package/dist/cli/output/console.d.ts +31 -0
- package/dist/cli/output/console.d.ts.map +1 -0
- package/dist/cli/output/console.js +571 -0
- package/dist/cli/output/console.js.map +1 -0
- package/dist/cli/output/html.d.ts +20 -0
- package/dist/cli/output/html.d.ts.map +1 -0
- package/dist/cli/output/html.js +339 -0
- package/dist/cli/output/html.js.map +1 -0
- package/dist/cli/output/json.d.ts +8 -0
- package/dist/cli/output/json.d.ts.map +1 -0
- package/dist/cli/output/json.js +46 -0
- package/dist/cli/output/json.js.map +1 -0
- package/dist/cli/output/markdown.d.ts +17 -0
- package/dist/cli/output/markdown.d.ts.map +1 -0
- package/dist/cli/output/markdown.js +323 -0
- package/dist/cli/output/markdown.js.map +1 -0
- package/dist/cli/output/stats.d.ts +35 -0
- package/dist/cli/output/stats.d.ts.map +1 -0
- package/dist/cli/output/stats.js +63 -0
- package/dist/cli/output/stats.js.map +1 -0
- package/dist/cli/output/terminal-markdown.d.ts +23 -0
- package/dist/cli/output/terminal-markdown.d.ts.map +1 -0
- package/dist/cli/output/terminal-markdown.js +159 -0
- package/dist/cli/output/terminal-markdown.js.map +1 -0
- package/dist/config/index.d.ts +27 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +266 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +179 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +85 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/gitignore/index.d.ts +5 -0
- package/dist/gitignore/index.d.ts.map +1 -0
- package/dist/gitignore/index.js +5 -0
- package/dist/gitignore/index.js.map +1 -0
- package/dist/gitignore/parser.d.ts +32 -0
- package/dist/gitignore/parser.d.ts.map +1 -0
- package/dist/gitignore/parser.js +110 -0
- package/dist/gitignore/parser.js.map +1 -0
- package/dist/gitignore/parser.test.d.ts +2 -0
- package/dist/gitignore/parser.test.d.ts.map +1 -0
- package/dist/gitignore/parser.test.js +217 -0
- package/dist/gitignore/parser.test.js.map +1 -0
- package/dist/i18n/index.d.ts +19 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +43 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locales/en.json +320 -0
- package/dist/i18n/locales/ru.json +320 -0
- package/dist/i18n/locales/zh.json +320 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +156 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/metrics/complexity/cognitive.d.ts +25 -0
- package/dist/metrics/complexity/cognitive.d.ts.map +1 -0
- package/dist/metrics/complexity/cognitive.js +109 -0
- package/dist/metrics/complexity/cognitive.js.map +1 -0
- package/dist/metrics/complexity/cyclomatic.d.ts +21 -0
- package/dist/metrics/complexity/cyclomatic.d.ts.map +1 -0
- package/dist/metrics/complexity/cyclomatic.js +111 -0
- package/dist/metrics/complexity/cyclomatic.js.map +1 -0
- package/dist/metrics/complexity/nesting-depth.d.ts +19 -0
- package/dist/metrics/complexity/nesting-depth.d.ts.map +1 -0
- package/dist/metrics/complexity/nesting-depth.js +97 -0
- package/dist/metrics/complexity/nesting-depth.js.map +1 -0
- package/dist/metrics/documentation/comment-ratio.d.ts +21 -0
- package/dist/metrics/documentation/comment-ratio.d.ts.map +1 -0
- package/dist/metrics/documentation/comment-ratio.js +91 -0
- package/dist/metrics/documentation/comment-ratio.js.map +1 -0
- package/dist/metrics/duplication/code-duplication.d.ts +24 -0
- package/dist/metrics/duplication/code-duplication.d.ts.map +1 -0
- package/dist/metrics/duplication/code-duplication.js +167 -0
- package/dist/metrics/duplication/code-duplication.js.map +1 -0
- package/dist/metrics/duplication/code-duplication.test.d.ts +2 -0
- package/dist/metrics/duplication/code-duplication.test.d.ts.map +1 -0
- package/dist/metrics/duplication/code-duplication.test.js +612 -0
- package/dist/metrics/duplication/code-duplication.test.js.map +1 -0
- package/dist/metrics/error/error-handling.d.ts +23 -0
- package/dist/metrics/error/error-handling.d.ts.map +1 -0
- package/dist/metrics/error/error-handling.js +164 -0
- package/dist/metrics/error/error-handling.js.map +1 -0
- package/dist/metrics/error/error-handling.test.d.ts +2 -0
- package/dist/metrics/error/error-handling.test.d.ts.map +1 -0
- package/dist/metrics/error/error-handling.test.js +349 -0
- package/dist/metrics/error/error-handling.test.js.map +1 -0
- package/dist/metrics/index.d.ts +21 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +50 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/naming/convention.d.ts +22 -0
- package/dist/metrics/naming/convention.d.ts.map +1 -0
- package/dist/metrics/naming/convention.js +117 -0
- package/dist/metrics/naming/convention.js.map +1 -0
- package/dist/metrics/size/file-length.d.ts +19 -0
- package/dist/metrics/size/file-length.d.ts.map +1 -0
- package/dist/metrics/size/file-length.js +68 -0
- package/dist/metrics/size/file-length.js.map +1 -0
- package/dist/metrics/size/function-length.d.ts +20 -0
- package/dist/metrics/size/function-length.d.ts.map +1 -0
- package/dist/metrics/size/function-length.js +101 -0
- package/dist/metrics/size/function-length.js.map +1 -0
- package/dist/metrics/size/parameter-count.d.ts +19 -0
- package/dist/metrics/size/parameter-count.d.ts.map +1 -0
- package/dist/metrics/size/parameter-count.js +97 -0
- package/dist/metrics/size/parameter-count.js.map +1 -0
- package/dist/metrics/structure/structure-analysis.d.ts +24 -0
- package/dist/metrics/structure/structure-analysis.d.ts.map +1 -0
- package/dist/metrics/structure/structure-analysis.js +223 -0
- package/dist/metrics/structure/structure-analysis.js.map +1 -0
- package/dist/metrics/structure/structure-analysis.test.d.ts +2 -0
- package/dist/metrics/structure/structure-analysis.test.d.ts.map +1 -0
- package/dist/metrics/structure/structure-analysis.test.js +342 -0
- package/dist/metrics/structure/structure-analysis.test.js.map +1 -0
- package/dist/metrics/types.d.ts +71 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +5 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/parser/generic-parser.d.ts +28 -0
- package/dist/parser/generic-parser.d.ts.map +1 -0
- package/dist/parser/generic-parser.js +218 -0
- package/dist/parser/generic-parser.js.map +1 -0
- package/dist/parser/index.d.ts +19 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +52 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/regex-parser.d.ts +46 -0
- package/dist/parser/regex-parser.d.ts.map +1 -0
- package/dist/parser/regex-parser.js +560 -0
- package/dist/parser/regex-parser.js.map +1 -0
- package/dist/parser/tree-sitter-parser.d.ts +50 -0
- package/dist/parser/tree-sitter-parser.d.ts.map +1 -0
- package/dist/parser/tree-sitter-parser.js +707 -0
- package/dist/parser/tree-sitter-parser.js.map +1 -0
- package/dist/parser/types.d.ts +52 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +49 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/scoring/index.d.ts +14 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +80 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/utils/fs.d.ts +24 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +61 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +16 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +303 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/progress.d.ts +24 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +79 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/terminal.d.ts +62 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +207 -0
- package/dist/utils/terminal.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Markdown renderer
|
|
3
|
+
*
|
|
4
|
+
* Converts Markdown to chalk-styled terminal output with block-level state
|
|
5
|
+
* machine (code fences, tables, normal text) and placeholder-based inline
|
|
6
|
+
* formatting to prevent bold/italic matching inside code spans.
|
|
7
|
+
*/
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { getTerminalWidth, displayWidth, padEndByWidth, wrapAnsiLine } from './terminal.js';
|
|
10
|
+
/**
|
|
11
|
+
* Render a Markdown string to chalk-styled terminal output.
|
|
12
|
+
*
|
|
13
|
+
* @param markdown - Raw Markdown text
|
|
14
|
+
* @param indent - Number of spaces to prepend to every output line (default: 0)
|
|
15
|
+
* @returns Chalk-styled string ready for console.log
|
|
16
|
+
*/
|
|
17
|
+
export function renderMarkdownToTerminal(markdown, indent = 0) {
|
|
18
|
+
const lines = markdown.split('\n');
|
|
19
|
+
const output = [];
|
|
20
|
+
let state = 0 /* BlockState.Normal */;
|
|
21
|
+
let codeFence = '';
|
|
22
|
+
let tableBuffer = [];
|
|
23
|
+
const indentStr = indent > 0 ? ' '.repeat(indent) : '';
|
|
24
|
+
const contentWidth = Math.max(20, getTerminalWidth() - indent);
|
|
25
|
+
let prevBlank = false;
|
|
26
|
+
for (const raw of lines) {
|
|
27
|
+
if (state === 1 /* BlockState.FencedCode */) {
|
|
28
|
+
prevBlank = false;
|
|
29
|
+
if (isClosingFence(raw, codeFence)) {
|
|
30
|
+
state = 0 /* BlockState.Normal */;
|
|
31
|
+
codeFence = '';
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const wrapped = wrapAnsiLine(chalk.gray(` ${raw}`), contentWidth);
|
|
35
|
+
for (const seg of wrapped)
|
|
36
|
+
output.push(indentStr + seg);
|
|
37
|
+
}
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const fenceMatch = /^(\s*)(```+|~~~+)(.*)/.exec(raw);
|
|
41
|
+
if (fenceMatch) {
|
|
42
|
+
prevBlank = false;
|
|
43
|
+
if (state === 2 /* BlockState.Table */ && tableBuffer.length > 0) {
|
|
44
|
+
output.push(...renderTable(tableBuffer, indentStr));
|
|
45
|
+
tableBuffer = [];
|
|
46
|
+
}
|
|
47
|
+
state = 1 /* BlockState.FencedCode */;
|
|
48
|
+
codeFence = fenceMatch[2] ?? '';
|
|
49
|
+
const lang = (fenceMatch[3] ?? '').trim();
|
|
50
|
+
if (lang) {
|
|
51
|
+
output.push(indentStr + chalk.gray.dim(` [${lang}]`));
|
|
52
|
+
}
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const trimmed = raw.trimStart();
|
|
56
|
+
if (trimmed.startsWith('|') && trimmed.endsWith('|')) {
|
|
57
|
+
prevBlank = false;
|
|
58
|
+
if (state !== 2 /* BlockState.Table */) {
|
|
59
|
+
state = 2 /* BlockState.Table */;
|
|
60
|
+
tableBuffer = [];
|
|
61
|
+
}
|
|
62
|
+
tableBuffer.push(raw);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (state === 2 /* BlockState.Table */) {
|
|
66
|
+
if (tableBuffer.length > 0) {
|
|
67
|
+
output.push(...renderTable(tableBuffer, indentStr));
|
|
68
|
+
tableBuffer = [];
|
|
69
|
+
}
|
|
70
|
+
state = 0 /* BlockState.Normal */;
|
|
71
|
+
}
|
|
72
|
+
if (raw.trim() === '') {
|
|
73
|
+
if (prevBlank)
|
|
74
|
+
continue;
|
|
75
|
+
prevBlank = true;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
prevBlank = false;
|
|
79
|
+
}
|
|
80
|
+
const rendered = renderBlockLine(raw, contentWidth);
|
|
81
|
+
const wrapped = wrapAnsiLine(rendered.text, contentWidth, rendered.hangingIndent);
|
|
82
|
+
for (const seg of wrapped)
|
|
83
|
+
output.push(indentStr + seg);
|
|
84
|
+
}
|
|
85
|
+
if (state === 2 /* BlockState.Table */ && tableBuffer.length > 0) {
|
|
86
|
+
output.push(...renderTable(tableBuffer, indentStr));
|
|
87
|
+
}
|
|
88
|
+
return output.join('\n');
|
|
89
|
+
}
|
|
90
|
+
/** Check if a line closes the current fenced code block */
|
|
91
|
+
function isClosingFence(line, openFence) {
|
|
92
|
+
const trimmed = line.trim();
|
|
93
|
+
const fenceChar = openFence[0] ?? '`';
|
|
94
|
+
const minLen = openFence.length;
|
|
95
|
+
if (!trimmed.startsWith(fenceChar.repeat(minLen)))
|
|
96
|
+
return false;
|
|
97
|
+
return /^(`{3,}|~{3,})\s*$/.test(trimmed);
|
|
98
|
+
}
|
|
99
|
+
/** Parse a table row into cells, stripping leading/trailing pipes and whitespace */
|
|
100
|
+
function parseTableCells(row) {
|
|
101
|
+
const trimmed = row.trim();
|
|
102
|
+
const inner = trimmed.startsWith('|') ? trimmed.slice(1) : trimmed;
|
|
103
|
+
const stripped = inner.endsWith('|') ? inner.slice(0, -1) : inner;
|
|
104
|
+
return stripped.split('|').map((cell) => cell.trim());
|
|
105
|
+
}
|
|
106
|
+
/** Check if a row is a separator row (|---|---|) */
|
|
107
|
+
function isSeparatorRow(row) {
|
|
108
|
+
return /^\|[\s:|-]+\|$/.test(row.trim());
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Render a Markdown table with proper column alignment and borders.
|
|
112
|
+
*
|
|
113
|
+
* Calculates the display width of each column (accounting for CJK characters),
|
|
114
|
+
* then renders with box-drawing characters. Columns are truncated if the table
|
|
115
|
+
* would exceed terminal width.
|
|
116
|
+
*/
|
|
117
|
+
function renderTable(rows, indentStr) {
|
|
118
|
+
if (rows.length === 0)
|
|
119
|
+
return [];
|
|
120
|
+
// Parse data rows (skip separator rows)
|
|
121
|
+
const dataRows = [];
|
|
122
|
+
for (const row of rows) {
|
|
123
|
+
if (!isSeparatorRow(row)) {
|
|
124
|
+
dataRows.push(parseTableCells(row));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (dataRows.length === 0)
|
|
128
|
+
return rows.map((r) => indentStr + chalk.gray(r));
|
|
129
|
+
const firstRow = dataRows[0];
|
|
130
|
+
if (!firstRow)
|
|
131
|
+
return rows.map((r) => indentStr + chalk.gray(r));
|
|
132
|
+
const colCount = firstRow.length;
|
|
133
|
+
// Calculate max display width per column
|
|
134
|
+
const colWidths = new Array(colCount).fill(0);
|
|
135
|
+
for (const row of dataRows) {
|
|
136
|
+
for (let c = 0; c < colCount; c++) {
|
|
137
|
+
const cell = row[c] ?? '';
|
|
138
|
+
const width = displayWidth(cell);
|
|
139
|
+
if (width > (colWidths[c] ?? 0))
|
|
140
|
+
colWidths[c] = width;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Clamp total width to terminal width
|
|
144
|
+
const termWidth = getTerminalWidth();
|
|
145
|
+
const indentWidth = displayWidth(indentStr);
|
|
146
|
+
const overhead = 3 * colCount + 1;
|
|
147
|
+
const availableWidth = termWidth - indentWidth - overhead;
|
|
148
|
+
const totalContentWidth = colWidths.reduce((sum, w) => sum + w, 0);
|
|
149
|
+
if (totalContentWidth > availableWidth && availableWidth > colCount) {
|
|
150
|
+
// Proportionally shrink columns, minimum 3 chars each
|
|
151
|
+
const scale = availableWidth / totalContentWidth;
|
|
152
|
+
for (let c = 0; c < colCount; c++) {
|
|
153
|
+
colWidths[c] = Math.max(3, Math.floor((colWidths[c] ?? 0) * scale));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const output = [];
|
|
157
|
+
// Build horizontal separator
|
|
158
|
+
const hLine = '├' + colWidths.map((w) => '─'.repeat(w + 2)).join('┼') + '┤';
|
|
159
|
+
const topLine = '┌' + colWidths.map((w) => '─'.repeat(w + 2)).join('┬') + '┐';
|
|
160
|
+
const bottomLine = '└' + colWidths.map((w) => '─'.repeat(w + 2)).join('┴') + '┘';
|
|
161
|
+
output.push(indentStr + chalk.gray(topLine));
|
|
162
|
+
let isHeader = true;
|
|
163
|
+
for (const row of rows) {
|
|
164
|
+
if (isSeparatorRow(row)) {
|
|
165
|
+
output.push(indentStr + chalk.gray(hLine));
|
|
166
|
+
isHeader = false;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const cells = parseTableCells(row);
|
|
170
|
+
const formattedCells = cells.slice(0, colCount).map((cell, c) => {
|
|
171
|
+
const maxW = colWidths[c] ?? 0;
|
|
172
|
+
const cellWidth = displayWidth(cell);
|
|
173
|
+
const formatted = renderInline(cell);
|
|
174
|
+
if (cellWidth > maxW) {
|
|
175
|
+
const truncated = truncatePlainText(cell, maxW);
|
|
176
|
+
return padEndByWidth(renderInline(truncated), maxW);
|
|
177
|
+
}
|
|
178
|
+
return padEndByWidth(formatted, maxW + (displayWidth(formatted) - cellWidth));
|
|
179
|
+
});
|
|
180
|
+
const line = chalk.gray('│') +
|
|
181
|
+
formattedCells
|
|
182
|
+
.map((cell, c) => {
|
|
183
|
+
const maxW = colWidths[c] ?? 0;
|
|
184
|
+
const content = ` ${padEndByWidth(cell, maxW)} `;
|
|
185
|
+
return isHeader ? chalk.bold(content) : content;
|
|
186
|
+
})
|
|
187
|
+
.join(chalk.gray('│')) +
|
|
188
|
+
chalk.gray('│');
|
|
189
|
+
output.push(indentStr + line);
|
|
190
|
+
}
|
|
191
|
+
output.push(indentStr + chalk.gray(bottomLine));
|
|
192
|
+
return output;
|
|
193
|
+
}
|
|
194
|
+
/** Truncate plain text (no ANSI) to fit within maxWidth display columns */
|
|
195
|
+
function truncatePlainText(text, maxWidth) {
|
|
196
|
+
if (displayWidth(text) <= maxWidth)
|
|
197
|
+
return text;
|
|
198
|
+
let width = 0;
|
|
199
|
+
let result = '';
|
|
200
|
+
for (const char of text) {
|
|
201
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
202
|
+
const charWidth = (codePoint >= 0x1100 && codePoint <= 0x115f) ||
|
|
203
|
+
(codePoint >= 0x2e80 && codePoint <= 0x9fff) ||
|
|
204
|
+
(codePoint >= 0xac00 && codePoint <= 0xd7af) ||
|
|
205
|
+
(codePoint >= 0xf900 && codePoint <= 0xfaff) ||
|
|
206
|
+
(codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
|
|
207
|
+
(codePoint >= 0xff01 && codePoint <= 0xff60) ||
|
|
208
|
+
(codePoint >= 0x20000 && codePoint <= 0x3134f)
|
|
209
|
+
? 2
|
|
210
|
+
: 1;
|
|
211
|
+
if (width + charWidth > maxWidth - 1)
|
|
212
|
+
break;
|
|
213
|
+
result += char;
|
|
214
|
+
width += charWidth;
|
|
215
|
+
}
|
|
216
|
+
return result + '…';
|
|
217
|
+
}
|
|
218
|
+
/** Render a single non-code, non-table line with block-level detection */
|
|
219
|
+
function renderBlockLine(line, contentWidth) {
|
|
220
|
+
// Horizontal rule — must come before list detection (--- could be confused)
|
|
221
|
+
if (/^(\s*)([-*_])\s*(\2\s*){2,}$/.test(line)) {
|
|
222
|
+
return { text: chalk.gray('─'.repeat(contentWidth)), hangingIndent: 0 };
|
|
223
|
+
}
|
|
224
|
+
// ATX headings (# through ######)
|
|
225
|
+
const headingMatch = /^(#{1,6})\s+(.*?)(?:\s+#+\s*)?$/.exec(line);
|
|
226
|
+
if (headingMatch) {
|
|
227
|
+
const level = (headingMatch[1] ?? '').length;
|
|
228
|
+
const text = renderInline(headingMatch[2] ?? '');
|
|
229
|
+
if (level === 1)
|
|
230
|
+
return { text: chalk.bold.yellow(text), hangingIndent: 0 };
|
|
231
|
+
if (level === 2)
|
|
232
|
+
return { text: chalk.bold.cyan(text), hangingIndent: 0 };
|
|
233
|
+
if (level === 3)
|
|
234
|
+
return { text: chalk.bold.magenta(text), hangingIndent: 0 };
|
|
235
|
+
if (level === 4)
|
|
236
|
+
return { text: chalk.bold.blue(text), hangingIndent: 0 };
|
|
237
|
+
return { text: chalk.bold(text), hangingIndent: 0 };
|
|
238
|
+
}
|
|
239
|
+
// Blockquote (supports nested `>>`)
|
|
240
|
+
const bqMatch = /^(\s*>)+\s?(.*)/.exec(line);
|
|
241
|
+
if (bqMatch) {
|
|
242
|
+
const depth = (line.match(/>/g) || []).length;
|
|
243
|
+
const prefix = chalk.gray(' │ '.repeat(depth));
|
|
244
|
+
const content = bqMatch[2] ?? '';
|
|
245
|
+
return { text: prefix + chalk.gray(renderInline(content)), hangingIndent: depth * 4 };
|
|
246
|
+
}
|
|
247
|
+
// Unordered list item (-, *, +) with indent awareness
|
|
248
|
+
const ulMatch = /^(\s*)([-*+])\s+(.*)/.exec(line);
|
|
249
|
+
if (ulMatch) {
|
|
250
|
+
const listIndent = ulMatch[1] ?? '';
|
|
251
|
+
return {
|
|
252
|
+
text: `${listIndent} • ${renderInline(ulMatch[3] ?? '')}`,
|
|
253
|
+
hangingIndent: listIndent.length + 4,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// Ordered list item
|
|
257
|
+
const olMatch = /^(\s*)(\d+)[.)]\s+(.*)/.exec(line);
|
|
258
|
+
if (olMatch) {
|
|
259
|
+
const listIndent = olMatch[1] ?? '';
|
|
260
|
+
const numStr = olMatch[2] ?? '';
|
|
261
|
+
return {
|
|
262
|
+
text: `${listIndent} ${numStr}. ${renderInline(olMatch[3] ?? '')}`,
|
|
263
|
+
hangingIndent: listIndent.length + 2 + numStr.length + 2,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
// Plain paragraph / text
|
|
267
|
+
return { text: renderInline(line), hangingIndent: 0 };
|
|
268
|
+
}
|
|
269
|
+
// Inline code placeholders — extracted first so bold/italic won't match inside code
|
|
270
|
+
const PLACEHOLDER_PREFIX = '\x00CODE';
|
|
271
|
+
const PLACEHOLDER_SUFFIX = '\x00';
|
|
272
|
+
/** Apply inline Markdown formatting (code, links, bold, italic, strikethrough) */
|
|
273
|
+
function renderInline(text) {
|
|
274
|
+
// Extract inline code spans into placeholders to protect from further formatting
|
|
275
|
+
const codeSpans = [];
|
|
276
|
+
let processed = text.replace(/`([^`]+)`/g, (_, code) => {
|
|
277
|
+
const idx = codeSpans.length;
|
|
278
|
+
codeSpans.push(chalk.cyan(code));
|
|
279
|
+
return `${PLACEHOLDER_PREFIX}${idx}${PLACEHOLDER_SUFFIX}`;
|
|
280
|
+
});
|
|
281
|
+
// Links: [text](url)
|
|
282
|
+
processed = processed.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, linkText, url) => `${chalk.cyan(linkText)} ${chalk.gray.dim(`(${url})`)}`);
|
|
283
|
+
// Images: 
|
|
284
|
+
processed = processed.replace(/!\[([^\]]*)\]\([^)]+\)/g, (_, alt) => chalk.dim(`[${alt || 'image'}]`));
|
|
285
|
+
// Bold + italic (***text*** or ___text___)
|
|
286
|
+
processed = processed.replace(/(\*{3}|_{3})(.+?)\1/g, (_, _marker, content) => chalk.bold.dim(content));
|
|
287
|
+
// Bold (**text** or __text__)
|
|
288
|
+
processed = processed.replace(/(\*{2}|_{2})(.+?)\1/g, (_, _marker, content) => chalk.bold(content));
|
|
289
|
+
// Italic (*text* or _text_) — dim as terminal italic fallback
|
|
290
|
+
// Negative lookbehind/ahead prevents matching inside ** pairs
|
|
291
|
+
processed = processed.replace(/(?<![*_])([*_])(?!\1)(.+?)(?<!\1)\1(?!\1)/g, (_, _marker, content) => chalk.dim(content));
|
|
292
|
+
// Strikethrough (~~text~~)
|
|
293
|
+
processed = processed.replace(/~~(.+?)~~/g, (_, content) => chalk.strikethrough(content));
|
|
294
|
+
// Restore inline code placeholders
|
|
295
|
+
for (let i = 0; i < codeSpans.length; i++) {
|
|
296
|
+
const span = codeSpans[i];
|
|
297
|
+
if (span === undefined)
|
|
298
|
+
continue;
|
|
299
|
+
processed = processed.replace(`${PLACEHOLDER_PREFIX}${i}${PLACEHOLDER_SUFFIX}`, span);
|
|
300
|
+
}
|
|
301
|
+
return processed;
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQ5F;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB,EAAE,MAAM,GAAG,CAAC;IACnE,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,4BAAoB,CAAC;IAC9B,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC,CAAC;IAC/D,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,IAAI,KAAK,kCAA0B,EAAE,CAAC;YACpC,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC;gBACnC,KAAK,4BAAoB,CAAC;gBAC1B,SAAS,GAAG,EAAE,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;gBACnE,KAAK,MAAM,GAAG,IAAI,OAAO;oBAAE,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;YAC1D,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,UAAU,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,KAAK,6BAAqB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzD,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;gBACpD,WAAW,GAAG,EAAE,CAAC;YACnB,CAAC;YACD,KAAK,gCAAwB,CAAC;YAC9B,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;YACzD,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;QAChC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACrD,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,KAAK,6BAAqB,EAAE,CAAC;gBAC/B,KAAK,2BAAmB,CAAC;gBACzB,WAAW,GAAG,EAAE,CAAC;YACnB,CAAC;YACD,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QAED,IAAI,KAAK,6BAAqB,EAAE,CAAC;YAC/B,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;gBACpD,WAAW,GAAG,EAAE,CAAC;YACnB,CAAC;YACD,KAAK,4BAAoB,CAAC;QAC5B,CAAC;QAED,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACtB,IAAI,SAAS;gBAAE,SAAS;YACxB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;QAED,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QAClF,KAAK,MAAM,GAAG,IAAI,OAAO;YAAE,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,KAAK,6BAAqB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,2DAA2D;AAC3D,SAAS,cAAc,CAAC,IAAY,EAAE,SAAiB;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;IACtC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IAChC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,oFAAoF;AACpF,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,oDAAoD;AACpD,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,IAAc,EAAE,SAAiB;IACpD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,wCAAwC;IACxC,MAAM,QAAQ,GAAe,EAAE,CAAC;IAEhC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7E,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEjC,yCAAyC;IACzC,MAAM,SAAS,GAAa,IAAI,KAAK,CAAS,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QACxD,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;IAClC,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC1D,MAAM,iBAAiB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnE,IAAI,iBAAiB,GAAG,cAAc,IAAI,cAAc,GAAG,QAAQ,EAAE,CAAC;QACpE,sDAAsD;QACtD,MAAM,KAAK,GAAG,cAAc,GAAG,iBAAiB,CAAC;QACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,6BAA6B;IAC7B,MAAM,KAAK,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC5E,MAAM,OAAO,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC9E,MAAM,UAAU,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAEjF,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAE7C,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,QAAQ,GAAG,KAAK,CAAC;YACjB,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YAC9D,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,SAAS,GAAG,IAAI,EAAE,CAAC;gBACrB,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChD,OAAO,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,aAAa,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GACR,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;YACf,cAAc;iBACX,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACf,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC/B,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;gBACjD,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAClD,CAAC,CAAC;iBACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElB,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAEhD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2EAA2E;AAC3E,SAAS,iBAAiB,CAAC,IAAY,EAAE,QAAgB;IACvD,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,SAAS,GACb,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;YAC5C,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;YAC5C,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;YAC5C,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;YAC5C,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;YAC5C,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;YAC5C,CAAC,SAAS,IAAI,OAAO,IAAI,SAAS,IAAI,OAAO,CAAC;YAC5C,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,CAAC,CAAC;QACR,IAAI,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,CAAC;YAAE,MAAM;QAC5C,MAAM,IAAI,IAAI,CAAC;QACf,KAAK,IAAI,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,GAAG,GAAG,CAAC;AACtB,CAAC;AAOD,0EAA0E;AAC1E,SAAS,eAAe,CAAC,IAAY,EAAE,YAAoB;IACzD,4EAA4E;IAC5E,IAAI,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,kCAAkC;IAClC,MAAM,YAAY,GAAG,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjD,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAC5E,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAC1E,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAC7E,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,oCAAoC;IACpC,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC;IACxF,CAAC;IAED,sDAAsD;IACtD,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,OAAO;YACL,IAAI,EAAE,GAAG,UAAU,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC;SACrC,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,MAAM,OAAO,GAAG,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,GAAG,UAAU,KAAK,MAAM,KAAK,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE;YACnE,aAAa,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,oFAAoF;AACpF,MAAM,kBAAkB,GAAG,UAAU,CAAC;AACtC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,kFAAkF;AAClF,SAAS,YAAY,CAAC,IAAY;IAChC,iFAAiF;IACjF,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,EAAE;QAC7D,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC;QAC7B,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,OAAO,GAAG,kBAAkB,GAAG,GAAG,GAAG,kBAAkB,EAAE,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,qBAAqB;IACrB,SAAS,GAAG,SAAS,CAAC,OAAO,CAC3B,0BAA0B,EAC1B,CAAC,CAAC,EAAE,QAAgB,EAAE,GAAW,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAC9F,CAAC;IAEF,sBAAsB;IACtB,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAC,EAAE,GAAW,EAAE,EAAE,CAC1E,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,CACjC,CAAC;IAEF,2CAA2C;IAC3C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,OAAe,EAAE,OAAe,EAAE,EAAE,CAC5F,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CACxB,CAAC;IAEF,8BAA8B;IAC9B,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,OAAe,EAAE,OAAe,EAAE,EAAE,CAC5F,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CACpB,CAAC;IAEF,8DAA8D;IAC9D,8DAA8D;IAC9D,SAAS,GAAG,SAAS,CAAC,OAAO,CAC3B,4CAA4C,EAC5C,CAAC,CAAC,EAAE,OAAe,EAAE,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAC5D,CAAC;IAEF,2BAA2B;IAC3B,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IAElG,mCAAmC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,kBAAkB,GAAG,CAAC,GAAG,kBAAkB,EAAE,EAAE,IAAI,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress display utilities
|
|
3
|
+
*/
|
|
4
|
+
import { type Ora } from 'ora';
|
|
5
|
+
export declare function createSpinner(text: string): Ora;
|
|
6
|
+
export declare function createProgressBar(total: number, label: string): ProgressBar;
|
|
7
|
+
export declare class ProgressBar {
|
|
8
|
+
private current;
|
|
9
|
+
private total;
|
|
10
|
+
private label;
|
|
11
|
+
private spinner;
|
|
12
|
+
private startTime;
|
|
13
|
+
private barWidth;
|
|
14
|
+
constructor(total: number, label: string);
|
|
15
|
+
start(): void;
|
|
16
|
+
increment(): void;
|
|
17
|
+
update(current: number): void;
|
|
18
|
+
succeed(text?: string): void;
|
|
19
|
+
fail(text?: string): void;
|
|
20
|
+
private formatText;
|
|
21
|
+
private renderBar;
|
|
22
|
+
private getETA;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/utils/progress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAGpC,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAM/C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAE3E;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAM;gBAEV,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAUxC,KAAK,IAAI,IAAI;IAKb,SAAS,IAAI,IAAI;IAKjB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5B,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,MAAM;CAYf"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress display utilities
|
|
3
|
+
*/
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
export function createSpinner(text) {
|
|
7
|
+
return ora({
|
|
8
|
+
text,
|
|
9
|
+
spinner: 'dots',
|
|
10
|
+
color: 'cyan',
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export function createProgressBar(total, label) {
|
|
14
|
+
return new ProgressBar(total, label);
|
|
15
|
+
}
|
|
16
|
+
export class ProgressBar {
|
|
17
|
+
current = 0;
|
|
18
|
+
total;
|
|
19
|
+
label;
|
|
20
|
+
spinner;
|
|
21
|
+
startTime = 0;
|
|
22
|
+
barWidth = 20;
|
|
23
|
+
constructor(total, label) {
|
|
24
|
+
this.total = total;
|
|
25
|
+
this.label = label;
|
|
26
|
+
this.spinner = ora({
|
|
27
|
+
text: this.formatText(),
|
|
28
|
+
spinner: 'dots',
|
|
29
|
+
color: 'cyan',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
start() {
|
|
33
|
+
this.startTime = Date.now();
|
|
34
|
+
this.spinner.start();
|
|
35
|
+
}
|
|
36
|
+
increment() {
|
|
37
|
+
this.current++;
|
|
38
|
+
this.spinner.text = this.formatText();
|
|
39
|
+
}
|
|
40
|
+
update(current) {
|
|
41
|
+
this.current = current;
|
|
42
|
+
this.spinner.text = this.formatText();
|
|
43
|
+
}
|
|
44
|
+
succeed(text) {
|
|
45
|
+
this.spinner.succeed(text || this.formatText());
|
|
46
|
+
}
|
|
47
|
+
fail(text) {
|
|
48
|
+
this.spinner.fail(text);
|
|
49
|
+
}
|
|
50
|
+
formatText() {
|
|
51
|
+
const percent = this.total > 0 ? Math.round((this.current / this.total) * 100) : 0;
|
|
52
|
+
const bar = this.renderBar(percent);
|
|
53
|
+
const stats = chalk.gray(`[${this.current}/${this.total}]`);
|
|
54
|
+
const percentStr = chalk.cyan(`${percent}%`);
|
|
55
|
+
const eta = this.getETA();
|
|
56
|
+
return `${this.label} ${bar} ${stats} ${percentStr}${eta}`;
|
|
57
|
+
}
|
|
58
|
+
renderBar(percent) {
|
|
59
|
+
const filled = Math.round((percent / 100) * this.barWidth);
|
|
60
|
+
const empty = this.barWidth - filled;
|
|
61
|
+
const filledBar = chalk.cyan('█'.repeat(filled));
|
|
62
|
+
const emptyBar = chalk.gray('░'.repeat(empty));
|
|
63
|
+
return `${filledBar}${emptyBar}`;
|
|
64
|
+
}
|
|
65
|
+
getETA() {
|
|
66
|
+
if (this.current === 0 || this.startTime === 0)
|
|
67
|
+
return '';
|
|
68
|
+
const elapsed = Date.now() - this.startTime;
|
|
69
|
+
const rate = this.current / elapsed;
|
|
70
|
+
const remaining = this.total - this.current;
|
|
71
|
+
const eta = remaining / rate;
|
|
72
|
+
if (eta < 1000)
|
|
73
|
+
return '';
|
|
74
|
+
if (eta < 60000)
|
|
75
|
+
return chalk.gray(` ~${Math.round(eta / 1000)}s`);
|
|
76
|
+
return chalk.gray(` ~${Math.round(eta / 60000)}m`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/utils/progress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal display utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides terminal width detection, Unicode-aware string width calculation,
|
|
5
|
+
* and display-width-based string padding/truncation for proper CJK alignment.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Get current terminal width.
|
|
9
|
+
*
|
|
10
|
+
* Falls back to 80 columns when stdout is not a TTY (e.g. piped output, CI).
|
|
11
|
+
* Clamped to [60, 200] to prevent degenerate layouts on extremely narrow
|
|
12
|
+
* or wide terminals.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getTerminalWidth(): number;
|
|
15
|
+
/**
|
|
16
|
+
* Calculate the display width of a string in terminal columns.
|
|
17
|
+
*
|
|
18
|
+
* Strips ANSI escape codes before measuring. CJK and other East Asian
|
|
19
|
+
* wide characters count as 2 columns; all other printable characters
|
|
20
|
+
* count as 1 column. Control characters (except ANSI sequences) are
|
|
21
|
+
* counted as 0 columns.
|
|
22
|
+
*
|
|
23
|
+
* @param str - Input string, may contain ANSI escape codes
|
|
24
|
+
* @returns Number of terminal columns the string occupies
|
|
25
|
+
*/
|
|
26
|
+
export declare function displayWidth(str: string): number;
|
|
27
|
+
/**
|
|
28
|
+
* Pad a string with trailing spaces to reach the target display width.
|
|
29
|
+
*
|
|
30
|
+
* Unlike `String.prototype.padEnd`, this accounts for CJK characters
|
|
31
|
+
* that occupy 2 terminal columns. If the string already meets or exceeds
|
|
32
|
+
* the target width, it is returned unchanged.
|
|
33
|
+
*
|
|
34
|
+
* @param str - Input string to pad
|
|
35
|
+
* @param targetWidth - Desired display width in terminal columns
|
|
36
|
+
* @returns Padded string
|
|
37
|
+
*/
|
|
38
|
+
export declare function padEndByWidth(str: string, targetWidth: number): string;
|
|
39
|
+
/**
|
|
40
|
+
* Truncate a string to fit within a maximum display width.
|
|
41
|
+
*
|
|
42
|
+
* If the string exceeds `maxWidth`, it is truncated and an ellipsis suffix
|
|
43
|
+
* is appended. CJK characters are handled correctly — truncation never
|
|
44
|
+
* splits a wide character. ANSI escape codes are preserved for characters
|
|
45
|
+
* that remain in the output.
|
|
46
|
+
*
|
|
47
|
+
* @param str - Input string (plain text, no ANSI codes expected)
|
|
48
|
+
* @param maxWidth - Maximum display width in terminal columns
|
|
49
|
+
* @param suffix - Suffix to append when truncated (default: "..")
|
|
50
|
+
* @returns Truncated string fitting within maxWidth columns
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* Wrap a string containing ANSI escape codes to fit within maxWidth display columns.
|
|
54
|
+
*
|
|
55
|
+
* Splits the line into segments that each fit within maxWidth. ANSI style state
|
|
56
|
+
* is tracked and replayed on continuation lines so colors/bold carry over correctly.
|
|
57
|
+
*
|
|
58
|
+
* @returns Array of line segments (at least one element)
|
|
59
|
+
*/
|
|
60
|
+
export declare function wrapAnsiLine(line: string, maxWidth: number, hangingIndent?: number): string[];
|
|
61
|
+
export declare function truncateByWidth(str: string, maxWidth: number, suffix?: string): string;
|
|
62
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/utils/terminal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4DH;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqBhD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAItE;AAED;;;;;;;;;;;;GAYG;AACH;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,SAAI,GAAG,MAAM,EAAE,CA8CxF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,MAAM,CAsBpF"}
|