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.
Files changed (245) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +256 -0
  3. package/bin/fuck-u-code-mcp.js +2 -0
  4. package/bin/fuck-u-code.js +2 -0
  5. package/bin/postinstall.js +53 -0
  6. package/dist/ai/index.d.ts +34 -0
  7. package/dist/ai/index.d.ts.map +1 -0
  8. package/dist/ai/index.js +227 -0
  9. package/dist/ai/index.js.map +1 -0
  10. package/dist/ai/prompts/code-review.d.ts +9 -0
  11. package/dist/ai/prompts/code-review.d.ts.map +1 -0
  12. package/dist/ai/prompts/code-review.js +61 -0
  13. package/dist/ai/prompts/code-review.js.map +1 -0
  14. package/dist/ai/providers/anthropic.d.ts +11 -0
  15. package/dist/ai/providers/anthropic.d.ts.map +1 -0
  16. package/dist/ai/providers/anthropic.js +60 -0
  17. package/dist/ai/providers/anthropic.js.map +1 -0
  18. package/dist/ai/providers/fetch.d.ts +10 -0
  19. package/dist/ai/providers/fetch.d.ts.map +1 -0
  20. package/dist/ai/providers/fetch.js +50 -0
  21. package/dist/ai/providers/fetch.js.map +1 -0
  22. package/dist/ai/providers/gemini.d.ts +12 -0
  23. package/dist/ai/providers/gemini.d.ts.map +1 -0
  24. package/dist/ai/providers/gemini.js +66 -0
  25. package/dist/ai/providers/gemini.js.map +1 -0
  26. package/dist/ai/providers/ollama.d.ts +11 -0
  27. package/dist/ai/providers/ollama.d.ts.map +1 -0
  28. package/dist/ai/providers/ollama.js +54 -0
  29. package/dist/ai/providers/ollama.js.map +1 -0
  30. package/dist/ai/providers/openai.d.ts +11 -0
  31. package/dist/ai/providers/openai.d.ts.map +1 -0
  32. package/dist/ai/providers/openai.js +52 -0
  33. package/dist/ai/providers/openai.js.map +1 -0
  34. package/dist/ai/selector.d.ts +19 -0
  35. package/dist/ai/selector.d.ts.map +1 -0
  36. package/dist/ai/selector.js +145 -0
  37. package/dist/ai/selector.js.map +1 -0
  38. package/dist/ai/types.d.ts +120 -0
  39. package/dist/ai/types.d.ts.map +1 -0
  40. package/dist/ai/types.js +6 -0
  41. package/dist/ai/types.js.map +1 -0
  42. package/dist/analyzer/concurrent-analyzer.d.ts +11 -0
  43. package/dist/analyzer/concurrent-analyzer.d.ts.map +1 -0
  44. package/dist/analyzer/concurrent-analyzer.js +67 -0
  45. package/dist/analyzer/concurrent-analyzer.js.map +1 -0
  46. package/dist/analyzer/file-discovery.d.ts +23 -0
  47. package/dist/analyzer/file-discovery.d.ts.map +1 -0
  48. package/dist/analyzer/file-discovery.js +64 -0
  49. package/dist/analyzer/file-discovery.js.map +1 -0
  50. package/dist/analyzer/index.d.ts +27 -0
  51. package/dist/analyzer/index.d.ts.map +1 -0
  52. package/dist/analyzer/index.js +64 -0
  53. package/dist/analyzer/index.js.map +1 -0
  54. package/dist/cli/commands/ai-review.d.ts +6 -0
  55. package/dist/cli/commands/ai-review.d.ts.map +1 -0
  56. package/dist/cli/commands/ai-review.js +213 -0
  57. package/dist/cli/commands/ai-review.js.map +1 -0
  58. package/dist/cli/commands/analyze.d.ts +6 -0
  59. package/dist/cli/commands/analyze.d.ts.map +1 -0
  60. package/dist/cli/commands/analyze.js +145 -0
  61. package/dist/cli/commands/analyze.js.map +1 -0
  62. package/dist/cli/commands/config.d.ts +6 -0
  63. package/dist/cli/commands/config.d.ts.map +1 -0
  64. package/dist/cli/commands/config.js +147 -0
  65. package/dist/cli/commands/config.js.map +1 -0
  66. package/dist/cli/commands/mcp-install.d.ts +9 -0
  67. package/dist/cli/commands/mcp-install.d.ts.map +1 -0
  68. package/dist/cli/commands/mcp-install.js +102 -0
  69. package/dist/cli/commands/mcp-install.js.map +1 -0
  70. package/dist/cli/index.d.ts +7 -0
  71. package/dist/cli/index.d.ts.map +1 -0
  72. package/dist/cli/index.js +69 -0
  73. package/dist/cli/index.js.map +1 -0
  74. package/dist/cli/output/ai-review-output.d.ts +20 -0
  75. package/dist/cli/output/ai-review-output.d.ts.map +1 -0
  76. package/dist/cli/output/ai-review-output.js +324 -0
  77. package/dist/cli/output/ai-review-output.js.map +1 -0
  78. package/dist/cli/output/console.d.ts +31 -0
  79. package/dist/cli/output/console.d.ts.map +1 -0
  80. package/dist/cli/output/console.js +571 -0
  81. package/dist/cli/output/console.js.map +1 -0
  82. package/dist/cli/output/html.d.ts +20 -0
  83. package/dist/cli/output/html.d.ts.map +1 -0
  84. package/dist/cli/output/html.js +339 -0
  85. package/dist/cli/output/html.js.map +1 -0
  86. package/dist/cli/output/json.d.ts +8 -0
  87. package/dist/cli/output/json.d.ts.map +1 -0
  88. package/dist/cli/output/json.js +46 -0
  89. package/dist/cli/output/json.js.map +1 -0
  90. package/dist/cli/output/markdown.d.ts +17 -0
  91. package/dist/cli/output/markdown.d.ts.map +1 -0
  92. package/dist/cli/output/markdown.js +323 -0
  93. package/dist/cli/output/markdown.js.map +1 -0
  94. package/dist/cli/output/stats.d.ts +35 -0
  95. package/dist/cli/output/stats.d.ts.map +1 -0
  96. package/dist/cli/output/stats.js +63 -0
  97. package/dist/cli/output/stats.js.map +1 -0
  98. package/dist/cli/output/terminal-markdown.d.ts +23 -0
  99. package/dist/cli/output/terminal-markdown.d.ts.map +1 -0
  100. package/dist/cli/output/terminal-markdown.js +159 -0
  101. package/dist/cli/output/terminal-markdown.js.map +1 -0
  102. package/dist/config/index.d.ts +27 -0
  103. package/dist/config/index.d.ts.map +1 -0
  104. package/dist/config/index.js +266 -0
  105. package/dist/config/index.js.map +1 -0
  106. package/dist/config/schema.d.ts +179 -0
  107. package/dist/config/schema.d.ts.map +1 -0
  108. package/dist/config/schema.js +85 -0
  109. package/dist/config/schema.js.map +1 -0
  110. package/dist/gitignore/index.d.ts +5 -0
  111. package/dist/gitignore/index.d.ts.map +1 -0
  112. package/dist/gitignore/index.js +5 -0
  113. package/dist/gitignore/index.js.map +1 -0
  114. package/dist/gitignore/parser.d.ts +32 -0
  115. package/dist/gitignore/parser.d.ts.map +1 -0
  116. package/dist/gitignore/parser.js +110 -0
  117. package/dist/gitignore/parser.js.map +1 -0
  118. package/dist/gitignore/parser.test.d.ts +2 -0
  119. package/dist/gitignore/parser.test.d.ts.map +1 -0
  120. package/dist/gitignore/parser.test.js +217 -0
  121. package/dist/gitignore/parser.test.js.map +1 -0
  122. package/dist/i18n/index.d.ts +19 -0
  123. package/dist/i18n/index.d.ts.map +1 -0
  124. package/dist/i18n/index.js +43 -0
  125. package/dist/i18n/index.js.map +1 -0
  126. package/dist/i18n/locales/en.json +320 -0
  127. package/dist/i18n/locales/ru.json +320 -0
  128. package/dist/i18n/locales/zh.json +320 -0
  129. package/dist/index.d.ts +5 -0
  130. package/dist/index.d.ts.map +1 -0
  131. package/dist/index.js +10 -0
  132. package/dist/index.js.map +1 -0
  133. package/dist/mcp/server.d.ts +9 -0
  134. package/dist/mcp/server.d.ts.map +1 -0
  135. package/dist/mcp/server.js +156 -0
  136. package/dist/mcp/server.js.map +1 -0
  137. package/dist/metrics/complexity/cognitive.d.ts +25 -0
  138. package/dist/metrics/complexity/cognitive.d.ts.map +1 -0
  139. package/dist/metrics/complexity/cognitive.js +109 -0
  140. package/dist/metrics/complexity/cognitive.js.map +1 -0
  141. package/dist/metrics/complexity/cyclomatic.d.ts +21 -0
  142. package/dist/metrics/complexity/cyclomatic.d.ts.map +1 -0
  143. package/dist/metrics/complexity/cyclomatic.js +111 -0
  144. package/dist/metrics/complexity/cyclomatic.js.map +1 -0
  145. package/dist/metrics/complexity/nesting-depth.d.ts +19 -0
  146. package/dist/metrics/complexity/nesting-depth.d.ts.map +1 -0
  147. package/dist/metrics/complexity/nesting-depth.js +97 -0
  148. package/dist/metrics/complexity/nesting-depth.js.map +1 -0
  149. package/dist/metrics/documentation/comment-ratio.d.ts +21 -0
  150. package/dist/metrics/documentation/comment-ratio.d.ts.map +1 -0
  151. package/dist/metrics/documentation/comment-ratio.js +91 -0
  152. package/dist/metrics/documentation/comment-ratio.js.map +1 -0
  153. package/dist/metrics/duplication/code-duplication.d.ts +24 -0
  154. package/dist/metrics/duplication/code-duplication.d.ts.map +1 -0
  155. package/dist/metrics/duplication/code-duplication.js +167 -0
  156. package/dist/metrics/duplication/code-duplication.js.map +1 -0
  157. package/dist/metrics/duplication/code-duplication.test.d.ts +2 -0
  158. package/dist/metrics/duplication/code-duplication.test.d.ts.map +1 -0
  159. package/dist/metrics/duplication/code-duplication.test.js +612 -0
  160. package/dist/metrics/duplication/code-duplication.test.js.map +1 -0
  161. package/dist/metrics/error/error-handling.d.ts +23 -0
  162. package/dist/metrics/error/error-handling.d.ts.map +1 -0
  163. package/dist/metrics/error/error-handling.js +164 -0
  164. package/dist/metrics/error/error-handling.js.map +1 -0
  165. package/dist/metrics/error/error-handling.test.d.ts +2 -0
  166. package/dist/metrics/error/error-handling.test.d.ts.map +1 -0
  167. package/dist/metrics/error/error-handling.test.js +349 -0
  168. package/dist/metrics/error/error-handling.test.js.map +1 -0
  169. package/dist/metrics/index.d.ts +21 -0
  170. package/dist/metrics/index.d.ts.map +1 -0
  171. package/dist/metrics/index.js +50 -0
  172. package/dist/metrics/index.js.map +1 -0
  173. package/dist/metrics/naming/convention.d.ts +22 -0
  174. package/dist/metrics/naming/convention.d.ts.map +1 -0
  175. package/dist/metrics/naming/convention.js +117 -0
  176. package/dist/metrics/naming/convention.js.map +1 -0
  177. package/dist/metrics/size/file-length.d.ts +19 -0
  178. package/dist/metrics/size/file-length.d.ts.map +1 -0
  179. package/dist/metrics/size/file-length.js +68 -0
  180. package/dist/metrics/size/file-length.js.map +1 -0
  181. package/dist/metrics/size/function-length.d.ts +20 -0
  182. package/dist/metrics/size/function-length.d.ts.map +1 -0
  183. package/dist/metrics/size/function-length.js +101 -0
  184. package/dist/metrics/size/function-length.js.map +1 -0
  185. package/dist/metrics/size/parameter-count.d.ts +19 -0
  186. package/dist/metrics/size/parameter-count.d.ts.map +1 -0
  187. package/dist/metrics/size/parameter-count.js +97 -0
  188. package/dist/metrics/size/parameter-count.js.map +1 -0
  189. package/dist/metrics/structure/structure-analysis.d.ts +24 -0
  190. package/dist/metrics/structure/structure-analysis.d.ts.map +1 -0
  191. package/dist/metrics/structure/structure-analysis.js +223 -0
  192. package/dist/metrics/structure/structure-analysis.js.map +1 -0
  193. package/dist/metrics/structure/structure-analysis.test.d.ts +2 -0
  194. package/dist/metrics/structure/structure-analysis.test.d.ts.map +1 -0
  195. package/dist/metrics/structure/structure-analysis.test.js +342 -0
  196. package/dist/metrics/structure/structure-analysis.test.js.map +1 -0
  197. package/dist/metrics/types.d.ts +71 -0
  198. package/dist/metrics/types.d.ts.map +1 -0
  199. package/dist/metrics/types.js +5 -0
  200. package/dist/metrics/types.js.map +1 -0
  201. package/dist/parser/generic-parser.d.ts +28 -0
  202. package/dist/parser/generic-parser.d.ts.map +1 -0
  203. package/dist/parser/generic-parser.js +218 -0
  204. package/dist/parser/generic-parser.js.map +1 -0
  205. package/dist/parser/index.d.ts +19 -0
  206. package/dist/parser/index.d.ts.map +1 -0
  207. package/dist/parser/index.js +52 -0
  208. package/dist/parser/index.js.map +1 -0
  209. package/dist/parser/regex-parser.d.ts +46 -0
  210. package/dist/parser/regex-parser.d.ts.map +1 -0
  211. package/dist/parser/regex-parser.js +560 -0
  212. package/dist/parser/regex-parser.js.map +1 -0
  213. package/dist/parser/tree-sitter-parser.d.ts +50 -0
  214. package/dist/parser/tree-sitter-parser.d.ts.map +1 -0
  215. package/dist/parser/tree-sitter-parser.js +707 -0
  216. package/dist/parser/tree-sitter-parser.js.map +1 -0
  217. package/dist/parser/types.d.ts +52 -0
  218. package/dist/parser/types.d.ts.map +1 -0
  219. package/dist/parser/types.js +49 -0
  220. package/dist/parser/types.js.map +1 -0
  221. package/dist/scoring/index.d.ts +14 -0
  222. package/dist/scoring/index.d.ts.map +1 -0
  223. package/dist/scoring/index.js +80 -0
  224. package/dist/scoring/index.js.map +1 -0
  225. package/dist/utils/fs.d.ts +24 -0
  226. package/dist/utils/fs.d.ts.map +1 -0
  227. package/dist/utils/fs.js +61 -0
  228. package/dist/utils/fs.js.map +1 -0
  229. package/dist/utils/logger.d.ts +13 -0
  230. package/dist/utils/logger.d.ts.map +1 -0
  231. package/dist/utils/logger.js +43 -0
  232. package/dist/utils/logger.js.map +1 -0
  233. package/dist/utils/markdown.d.ts +16 -0
  234. package/dist/utils/markdown.d.ts.map +1 -0
  235. package/dist/utils/markdown.js +303 -0
  236. package/dist/utils/markdown.js.map +1 -0
  237. package/dist/utils/progress.d.ts +24 -0
  238. package/dist/utils/progress.d.ts.map +1 -0
  239. package/dist/utils/progress.js +79 -0
  240. package/dist/utils/progress.js.map +1 -0
  241. package/dist/utils/terminal.d.ts +62 -0
  242. package/dist/utils/terminal.d.ts.map +1 -0
  243. package/dist/utils/terminal.js +207 -0
  244. package/dist/utils/terminal.js.map +1 -0
  245. 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: ![alt](url)
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"}