fln 1.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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +330 -0
  3. package/dist/api/fln.d.ts +3 -0
  4. package/dist/api/fln.d.ts.map +1 -0
  5. package/dist/api/fln.js +71 -0
  6. package/dist/api/index.d.ts +3 -0
  7. package/dist/api/index.d.ts.map +1 -0
  8. package/dist/api/index.js +2 -0
  9. package/dist/api/types.d.ts +34 -0
  10. package/dist/api/types.d.ts.map +1 -0
  11. package/dist/api/types.js +1 -0
  12. package/dist/cli/commandLine.d.ts +2 -0
  13. package/dist/cli/commandLine.d.ts.map +1 -0
  14. package/dist/cli/commandLine.js +120 -0
  15. package/dist/cli/help.d.ts +2 -0
  16. package/dist/cli/help.d.ts.map +1 -0
  17. package/dist/cli/help.js +40 -0
  18. package/dist/cli/index.d.ts +2 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +1 -0
  21. package/dist/cli/main.d.ts +3 -0
  22. package/dist/cli/main.d.ts.map +1 -0
  23. package/dist/cli/main.js +9 -0
  24. package/dist/cli/output/components/breakdown.d.ts +2 -0
  25. package/dist/cli/output/components/breakdown.d.ts.map +1 -0
  26. package/dist/cli/output/components/breakdown.js +21 -0
  27. package/dist/cli/output/components/errors.d.ts +6 -0
  28. package/dist/cli/output/components/errors.d.ts.map +1 -0
  29. package/dist/cli/output/components/errors.js +13 -0
  30. package/dist/cli/output/components/progressBar.d.ts +7 -0
  31. package/dist/cli/output/components/progressBar.d.ts.map +1 -0
  32. package/dist/cli/output/components/progressBar.js +38 -0
  33. package/dist/cli/output/components/summary.d.ts +8 -0
  34. package/dist/cli/output/components/summary.d.ts.map +1 -0
  35. package/dist/cli/output/components/summary.js +12 -0
  36. package/dist/cli/output/components/warnings.d.ts +6 -0
  37. package/dist/cli/output/components/warnings.d.ts.map +1 -0
  38. package/dist/cli/output/components/warnings.js +11 -0
  39. package/dist/cli/output/formatter.d.ts +5 -0
  40. package/dist/cli/output/formatter.d.ts.map +1 -0
  41. package/dist/cli/output/formatter.js +28 -0
  42. package/dist/cli/output/index.d.ts +8 -0
  43. package/dist/cli/output/index.d.ts.map +1 -0
  44. package/dist/cli/output/index.js +4 -0
  45. package/dist/cli/output/renderer.d.ts +21 -0
  46. package/dist/cli/output/renderer.d.ts.map +1 -0
  47. package/dist/cli/output/renderer.js +121 -0
  48. package/dist/cli/output/styles.d.ts +23 -0
  49. package/dist/cli/output/styles.d.ts.map +1 -0
  50. package/dist/cli/output/styles.js +26 -0
  51. package/dist/config/defaults.d.ts +3 -0
  52. package/dist/config/defaults.d.ts.map +1 -0
  53. package/dist/config/defaults.js +2 -0
  54. package/dist/config/index.d.ts +6 -0
  55. package/dist/config/index.d.ts.map +1 -0
  56. package/dist/config/index.js +5 -0
  57. package/dist/config/loader.d.ts +3 -0
  58. package/dist/config/loader.d.ts.map +1 -0
  59. package/dist/config/loader.js +11 -0
  60. package/dist/config/resolver.d.ts +8 -0
  61. package/dist/config/resolver.d.ts.map +1 -0
  62. package/dist/config/resolver.js +66 -0
  63. package/dist/config/types.d.ts +40 -0
  64. package/dist/config/types.d.ts.map +1 -0
  65. package/dist/config/types.js +1 -0
  66. package/dist/config/utils.d.ts +7 -0
  67. package/dist/config/utils.d.ts.map +1 -0
  68. package/dist/config/utils.js +161 -0
  69. package/dist/core/ignoreMatcher.d.ts +15 -0
  70. package/dist/core/ignoreMatcher.d.ts.map +1 -0
  71. package/dist/core/ignoreMatcher.js +97 -0
  72. package/dist/core/index.d.ts +8 -0
  73. package/dist/core/index.d.ts.map +1 -0
  74. package/dist/core/index.js +7 -0
  75. package/dist/core/renderOutput.d.ts +4 -0
  76. package/dist/core/renderOutput.d.ts.map +1 -0
  77. package/dist/core/renderOutput.js +218 -0
  78. package/dist/core/renderTree.d.ts +3 -0
  79. package/dist/core/renderTree.d.ts.map +1 -0
  80. package/dist/core/renderTree.js +23 -0
  81. package/dist/core/scanTree.d.ts +4 -0
  82. package/dist/core/scanTree.d.ts.map +1 -0
  83. package/dist/core/scanTree.js +348 -0
  84. package/dist/core/size.d.ts +4 -0
  85. package/dist/core/size.d.ts.map +1 -0
  86. package/dist/core/size.js +32 -0
  87. package/dist/core/statsCollector.d.ts +4 -0
  88. package/dist/core/statsCollector.d.ts.map +1 -0
  89. package/dist/core/statsCollector.js +28 -0
  90. package/dist/core/types.d.ts +53 -0
  91. package/dist/core/types.d.ts.map +1 -0
  92. package/dist/core/types.js +1 -0
  93. package/dist/index.d.ts +4 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +3 -0
  96. package/dist/infra/countTokens.d.ts +2 -0
  97. package/dist/infra/countTokens.d.ts.map +1 -0
  98. package/dist/infra/countTokens.js +186 -0
  99. package/dist/infra/datetime.d.ts +3 -0
  100. package/dist/infra/datetime.d.ts.map +1 -0
  101. package/dist/infra/datetime.js +15 -0
  102. package/dist/infra/index.d.ts +7 -0
  103. package/dist/infra/index.d.ts.map +1 -0
  104. package/dist/infra/index.js +6 -0
  105. package/dist/infra/logger.d.ts +19 -0
  106. package/dist/infra/logger.d.ts.map +1 -0
  107. package/dist/infra/logger.js +99 -0
  108. package/dist/infra/outputWriter.d.ts +15 -0
  109. package/dist/infra/outputWriter.d.ts.map +1 -0
  110. package/dist/infra/outputWriter.js +35 -0
  111. package/dist/infra/terminal.d.ts +91 -0
  112. package/dist/infra/terminal.d.ts.map +1 -0
  113. package/dist/infra/terminal.js +189 -0
  114. package/dist/infra/usageTracker.d.ts +3 -0
  115. package/dist/infra/usageTracker.d.ts.map +1 -0
  116. package/dist/infra/usageTracker.js +39 -0
  117. package/dist/version.d.ts +2 -0
  118. package/dist/version.d.ts.map +1 -0
  119. package/dist/version.js +1 -0
  120. package/package.json +79 -0
@@ -0,0 +1,186 @@
1
+ var CharCategory;
2
+ (function (CharCategory) {
3
+ CharCategory[CharCategory["Other"] = 0] = "Other";
4
+ CharCategory[CharCategory["Whitespace"] = 1] = "Whitespace";
5
+ CharCategory[CharCategory["Digit"] = 2] = "Digit";
6
+ CharCategory[CharCategory["Latin"] = 3] = "Latin";
7
+ CharCategory[CharCategory["Cyrillic"] = 4] = "Cyrillic";
8
+ CharCategory[CharCategory["Arabic"] = 5] = "Arabic";
9
+ CharCategory[CharCategory["CJK"] = 6] = "CJK";
10
+ CharCategory[CharCategory["Punctuation"] = 7] = "Punctuation";
11
+ })(CharCategory || (CharCategory = {}));
12
+ const CYRILLIC_CHARS_PER_TOKEN = 3.3;
13
+ const ARABIC_CHARS_PER_TOKEN = 2.7;
14
+ const LATIN_CHARS_PER_TOKEN = 4.7;
15
+ const CYR_START = 0x0400;
16
+ const CYR_END = 0x04FF;
17
+ const ARABIC_START = 0x0600;
18
+ const ARABIC_END = 0x06FF;
19
+ const CJK_MAIN_START = 0x4E00;
20
+ const CJK_MAIN_END = 0x9FFF;
21
+ const KANA_START = 0x3040;
22
+ const KANA_END = 0x30FF;
23
+ const SURROGATE_HIGH_START = 0xD800;
24
+ const SURROGATE_HIGH_END = 0xDBFF;
25
+ const LOWERCASE_MASK = 0x20;
26
+ const APOSTROPHE = 0x27;
27
+ const ASCII_MAP = new Uint8Array(128);
28
+ const COMMON_WORDS = new Set([
29
+ "the", "be", "to", "of", "and", "a", "in", "that", "have", "I",
30
+ "it", "for", "not", "on", "with", "he", "as", "you", "do", "at",
31
+ "this", "but", "his", "by", "from", "they", "we", "say", "her", "she",
32
+ "or", "an", "will", "my", "one", "all", "would", "there", "their",
33
+ "if", "const", "let", "var", "function", "return", "while", "for",
34
+ "async", "await", "class", "import", "export", "default", "new",
35
+ "else", "case", "break", "continue", "switch", "typeof", "void"
36
+ ]);
37
+ (function initializeAsciiMap() {
38
+ ASCII_MAP[0x09] = CharCategory.Whitespace;
39
+ ASCII_MAP[0x0A] = CharCategory.Whitespace;
40
+ ASCII_MAP[0x0D] = CharCategory.Whitespace;
41
+ ASCII_MAP[0x20] = CharCategory.Whitespace;
42
+ for (let i = 0x30; i <= 0x39; i++)
43
+ ASCII_MAP[i] = CharCategory.Digit;
44
+ for (let i = 0x41; i <= 0x5A; i++)
45
+ ASCII_MAP[i] = CharCategory.Latin;
46
+ for (let i = 0x61; i <= 0x7A; i++)
47
+ ASCII_MAP[i] = CharCategory.Latin;
48
+ const punctuation = "!\"#$%&()*+,-./:;<=>?@[\\]^_`{|}~";
49
+ for (let i = 0; i < punctuation.length; i++)
50
+ ASCII_MAP[punctuation.charCodeAt(i)] = CharCategory.Punctuation;
51
+ })();
52
+ export function countTokens(text) {
53
+ if (!text)
54
+ return 0;
55
+ const { length } = text;
56
+ let tokenCount = 0;
57
+ let index = 0;
58
+ while (index < length) {
59
+ const code = text.charCodeAt(index);
60
+ let category;
61
+ if (code < 128)
62
+ category = ASCII_MAP[code];
63
+ else if (code >= CYR_START && code <= CYR_END)
64
+ category = CharCategory.Cyrillic;
65
+ else if (code >= ARABIC_START && code <= ARABIC_END)
66
+ category = CharCategory.Arabic;
67
+ else if ((code >= CJK_MAIN_START && code <= CJK_MAIN_END) ||
68
+ (code >= KANA_START && code <= KANA_END))
69
+ category = CharCategory.CJK;
70
+ else {
71
+ if (code >= SURROGATE_HIGH_START && code <= SURROGATE_HIGH_END) {
72
+ index += 2;
73
+ tokenCount++;
74
+ continue;
75
+ }
76
+ category = CharCategory.Other;
77
+ }
78
+ switch (category) {
79
+ case CharCategory.Latin: {
80
+ let wordEnd = index + 1;
81
+ let nextCode;
82
+ while (wordEnd < length &&
83
+ (((nextCode = text.charCodeAt(wordEnd)) >= 0x61 && nextCode <= 0x7A) ||
84
+ (nextCode >= 0x41 && nextCode <= 0x5A)))
85
+ wordEnd++;
86
+ let hasContraction = false;
87
+ if (wordEnd < length && text.charCodeAt(wordEnd) === APOSTROPHE) {
88
+ const suffixStart = wordEnd + 1;
89
+ if (suffixStart < length) {
90
+ const char1 = text.charCodeAt(suffixStart) | LOWERCASE_MASK;
91
+ if (char1 === 0x73 || char1 === 0x74 || char1 === 0x6D || char1 === 0x64) {
92
+ wordEnd = suffixStart + 1;
93
+ hasContraction = true;
94
+ }
95
+ else if (suffixStart + 1 < length) {
96
+ const char2 = text.charCodeAt(suffixStart + 1) | LOWERCASE_MASK;
97
+ if ((char1 === 0x72 && char2 === 0x65) ||
98
+ (char1 === 0x76 && char2 === 0x65) ||
99
+ (char1 === 0x6C && char2 === 0x6C)) {
100
+ wordEnd = suffixStart + 2;
101
+ hasContraction = true;
102
+ }
103
+ }
104
+ }
105
+ }
106
+ const wordLength = wordEnd - index;
107
+ const word = text.slice(index, wordEnd).toLowerCase();
108
+ if (COMMON_WORDS.has(word) || wordLength <= 3)
109
+ tokenCount++;
110
+ else
111
+ tokenCount += Math.max(1, Math.round(wordLength / LATIN_CHARS_PER_TOKEN));
112
+ if (hasContraction)
113
+ tokenCount++;
114
+ index = wordEnd;
115
+ break;
116
+ }
117
+ case CharCategory.Whitespace: {
118
+ index++;
119
+ break;
120
+ }
121
+ case CharCategory.Digit: {
122
+ let digitEnd = index + 1;
123
+ let hasHexPrefix = false;
124
+ if (index > 0 && text.charCodeAt(index - 1) === 0x78 && index > 1 && text.charCodeAt(index - 2) === 0x30) {
125
+ hasHexPrefix = true;
126
+ while (digitEnd < length) {
127
+ const nextCode = text.charCodeAt(digitEnd);
128
+ if (!((nextCode >= 0x30 && nextCode <= 0x39) || (nextCode >= 0x41 && nextCode <= 0x46) || (nextCode >= 0x61 && nextCode <= 0x66)))
129
+ break;
130
+ digitEnd++;
131
+ }
132
+ }
133
+ else
134
+ while (digitEnd < length) {
135
+ const nextCode = text.charCodeAt(digitEnd);
136
+ if (nextCode < 0x30 || nextCode > 0x39)
137
+ break;
138
+ digitEnd++;
139
+ }
140
+ const digitCount = digitEnd - index;
141
+ if (hasHexPrefix || digitCount === 4)
142
+ tokenCount++;
143
+ else if (digitCount <= 2)
144
+ tokenCount++;
145
+ else
146
+ tokenCount += Math.ceil(digitCount / 3);
147
+ index = digitEnd;
148
+ break;
149
+ }
150
+ case CharCategory.Cyrillic: {
151
+ const start = index;
152
+ do
153
+ index++;
154
+ while (index < length && text.charCodeAt(index) >= CYR_START && text.charCodeAt(index) <= CYR_END);
155
+ const charCount = index - start;
156
+ tokenCount += Math.max(1, Math.round(charCount / CYRILLIC_CHARS_PER_TOKEN));
157
+ break;
158
+ }
159
+ case CharCategory.Arabic: {
160
+ const start = index;
161
+ do
162
+ index++;
163
+ while (index < length && text.charCodeAt(index) >= ARABIC_START && text.charCodeAt(index) <= ARABIC_END);
164
+ const charCount = index - start;
165
+ tokenCount += Math.max(1, Math.round(charCount / ARABIC_CHARS_PER_TOKEN));
166
+ break;
167
+ }
168
+ case CharCategory.CJK: {
169
+ tokenCount++;
170
+ index++;
171
+ break;
172
+ }
173
+ case CharCategory.Punctuation: {
174
+ tokenCount++;
175
+ index++;
176
+ break;
177
+ }
178
+ default: {
179
+ tokenCount++;
180
+ index++;
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ return tokenCount;
186
+ }
@@ -0,0 +1,3 @@
1
+ export declare function formatDateTime(): string;
2
+ export declare function parseGeneratedDate(value: string): string;
3
+ //# sourceMappingURL=datetime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datetime.d.ts","sourceRoot":"","sources":["../../src/infra/datetime.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,IAAI,MAAM,CASvC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKxD"}
@@ -0,0 +1,15 @@
1
+ const generatedDateRegex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/;
2
+ export function formatDateTime() {
3
+ const now = new Date();
4
+ const year = now.getFullYear();
5
+ const month = String(now.getMonth() + 1).padStart(2, "0");
6
+ const day = String(now.getDate()).padStart(2, "0");
7
+ const hours = String(now.getHours()).padStart(2, "0");
8
+ const minutes = String(now.getMinutes()).padStart(2, "0");
9
+ return `${year}-${month}-${day} ${hours}:${minutes}`;
10
+ }
11
+ export function parseGeneratedDate(value) {
12
+ if (!generatedDateRegex.test(value.trim()))
13
+ throw new Error(`Invalid generated date: "${value}". Expected format: YYYY-MM-DD HH:mm`);
14
+ return value.trim();
15
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./countTokens";
2
+ export * from "./datetime";
3
+ export * from "./logger";
4
+ export * from "./outputWriter";
5
+ export * from "./terminal";
6
+ export * from "./usageTracker";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/infra/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from "./countTokens";
2
+ export * from "./datetime";
3
+ export * from "./logger";
4
+ export * from "./outputWriter";
5
+ export * from "./terminal";
6
+ export * from "./usageTracker";
@@ -0,0 +1,19 @@
1
+ import type { LogLevel } from "$core";
2
+ type LoggerOptions = {
3
+ useAnsi: boolean;
4
+ logLevel: LogLevel;
5
+ };
6
+ export type Logger = {
7
+ info: (message: string) => void;
8
+ success: (message: string) => void;
9
+ warn: (message: string) => void;
10
+ error: (message: string) => void;
11
+ debug: (message: string) => void;
12
+ header: (text: string) => void;
13
+ section: (title: string, items: Record<string, number | string>) => void;
14
+ box: (title: string, content: string[], showDivider?: boolean) => void;
15
+ empty: () => void;
16
+ };
17
+ export declare function createLogger(options: LoggerOptions): Logger;
18
+ export {};
19
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/infra/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAStC,KAAK,aAAa,GAAG;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACzE,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACvE,KAAK,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAiH3D"}
@@ -0,0 +1,99 @@
1
+ import { ansi, getTerminalInfo, renderBox, symbols } from "./terminal";
2
+ export function createLogger(options) {
3
+ const { useAnsi, logLevel } = options;
4
+ const { width } = getTerminalInfo();
5
+ const isSilent = logLevel === "silent";
6
+ const isVerbose = logLevel === "verbose" || logLevel === "debug";
7
+ const formatMessage = (symbol, color, message) => {
8
+ if (!useAnsi)
9
+ return `${symbol} ${message}`;
10
+ return ` ${color}${symbol}${ansi.reset} ${message}`;
11
+ };
12
+ const writeInfo = (formatted) => {
13
+ if (!isSilent)
14
+ console.info(formatted);
15
+ };
16
+ return {
17
+ info: (message) => {
18
+ if (!isSilent)
19
+ if (useAnsi)
20
+ console.info(` ${ansi.dim}${message}${ansi.reset}`);
21
+ else
22
+ console.info(message);
23
+ },
24
+ success: (message) => {
25
+ writeInfo(formatMessage(symbols.check, ansi.green, message));
26
+ },
27
+ warn: (message) => {
28
+ if (!isSilent)
29
+ console.warn(formatMessage(symbols.warning, ansi.yellow, message));
30
+ },
31
+ error: (message) => {
32
+ console.error(formatMessage(symbols.cross, ansi.red, message));
33
+ },
34
+ debug: (message) => {
35
+ if (!isSilent && isVerbose)
36
+ if (useAnsi)
37
+ console.info(` ${ansi.dim}${symbols.info} ${message}${ansi.reset}`);
38
+ else
39
+ console.info(`${symbols.info} ${message}`);
40
+ },
41
+ header: (text) => {
42
+ if (isSilent)
43
+ return;
44
+ if (useAnsi) {
45
+ const boxWidth = Math.min(width - 4, 60);
46
+ const paddedText = text.padEnd(boxWidth - 4);
47
+ console.info("");
48
+ console.info(`${ansi.dim}${symbols.boxTopLeft}${symbols.boxHorizontal.repeat(boxWidth - 2)}${symbols.boxTopRight}${ansi.reset}`);
49
+ console.info(`${ansi.dim}${symbols.boxVertical}${ansi.reset}${ansi.bold}${paddedText}${ansi.reset} ${ansi.dim}${symbols.boxVertical}${ansi.reset}`);
50
+ console.info(`${ansi.dim}${symbols.boxBottomLeft}${symbols.boxHorizontal.repeat(boxWidth - 2)}${symbols.boxBottomRight}${ansi.reset}`);
51
+ console.info("");
52
+ }
53
+ else {
54
+ console.info("");
55
+ console.info(`=== ${text} ===`);
56
+ console.info("");
57
+ }
58
+ },
59
+ section: (title, items) => {
60
+ if (isSilent)
61
+ return;
62
+ if (useAnsi) {
63
+ console.info("");
64
+ console.info(`${ansi.bold}${title}${ansi.reset}`);
65
+ console.info("");
66
+ }
67
+ else {
68
+ console.info("");
69
+ console.info(title);
70
+ }
71
+ const maxKeyLength = Math.max(...Object.keys(items).map(key => key.length));
72
+ for (const [key, value] of Object.entries(items)) {
73
+ const paddedKey = key.padEnd(maxKeyLength);
74
+ if (useAnsi)
75
+ console.info(` ${ansi.dim}${paddedKey}${ansi.reset} ${value}`);
76
+ else
77
+ console.info(` ${paddedKey} ${value}`);
78
+ }
79
+ },
80
+ box: (title, content, showDivider = false) => {
81
+ if (isSilent)
82
+ return;
83
+ const boxWidth = Math.min(width - 4, 60);
84
+ const box = renderBox({
85
+ title,
86
+ content,
87
+ width: boxWidth,
88
+ useAnsi,
89
+ showDivider
90
+ });
91
+ console.info("");
92
+ console.info(box);
93
+ },
94
+ empty: () => {
95
+ if (!isSilent)
96
+ console.info("");
97
+ }
98
+ };
99
+ }
@@ -0,0 +1,15 @@
1
+ type OutputWriter = {
2
+ write: (text: string) => Promise<void>;
3
+ writeLine: (text: string) => Promise<void>;
4
+ getStats: () => {
5
+ sizeBytes: number;
6
+ tokenCount: number;
7
+ };
8
+ close: () => Promise<{
9
+ sizeBytes: number;
10
+ tokenCount: number;
11
+ }>;
12
+ };
13
+ export declare function createOutputWriter(outputFile: string, maxSizeBytes?: number): Promise<OutputWriter>;
14
+ export {};
15
+ //# sourceMappingURL=outputWriter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputWriter.d.ts","sourceRoot":"","sources":["../../src/infra/outputWriter.ts"],"names":[],"mappings":"AAOA,KAAK,YAAY,GAAG;IACnB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,KAAK,EAAE,MAAM,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AAEF,wBAAsB,kBAAkB,CACvC,UAAU,EAAE,MAAM,EAClB,YAAY,SAAI,GACd,OAAO,CAAC,YAAY,CAAC,CAoCvB"}
@@ -0,0 +1,35 @@
1
+ import { once } from "node:events";
2
+ import { createWriteStream } from "node:fs";
3
+ import { mkdir } from "node:fs/promises";
4
+ import { dirname } from "node:path";
5
+ import { countTokens } from "./countTokens";
6
+ export async function createOutputWriter(outputFile, maxSizeBytes = 0) {
7
+ const outputDirectory = dirname(outputFile);
8
+ if (outputDirectory !== ".")
9
+ await mkdir(outputDirectory, { recursive: true });
10
+ const stream = createWriteStream(outputFile, { encoding: "utf8" });
11
+ let bytesWritten = 0;
12
+ let totalTokenCount = 0;
13
+ const write = async (text) => {
14
+ const textBytes = Buffer.byteLength(text);
15
+ if (maxSizeBytes > 0 && bytesWritten + textBytes > maxSizeBytes)
16
+ throw new Error(`Output size would exceed maximum of ${maxSizeBytes} bytes`);
17
+ bytesWritten += textBytes;
18
+ totalTokenCount += countTokens(text);
19
+ if (!stream.write(text))
20
+ await once(stream, "drain");
21
+ };
22
+ return {
23
+ write,
24
+ writeLine: (text) => write(`${text}\n`),
25
+ getStats: () => ({ sizeBytes: bytesWritten, tokenCount: totalTokenCount }),
26
+ close: () => new Promise((resolve, reject) => {
27
+ stream.end((error) => {
28
+ if (error)
29
+ reject(error);
30
+ else
31
+ resolve({ sizeBytes: bytesWritten, tokenCount: totalTokenCount });
32
+ });
33
+ })
34
+ };
35
+ }
@@ -0,0 +1,91 @@
1
+ type TerminalInfo = {
2
+ width: number;
3
+ supportsAnsi: boolean;
4
+ };
5
+ export declare function getTerminalInfo(): TerminalInfo;
6
+ export declare function isTTY(): boolean;
7
+ export declare function shouldUseColors(): boolean;
8
+ export declare const ansi: {
9
+ cursorHide: string;
10
+ cursorShow: string;
11
+ cursorUp: (lines: number) => string;
12
+ cursorDown: (lines: number) => string;
13
+ cursorTo: (column: number) => string;
14
+ clearLine: string;
15
+ clearLineRight: string;
16
+ reset: string;
17
+ bold: string;
18
+ dim: string;
19
+ black: string;
20
+ red: string;
21
+ green: string;
22
+ yellow: string;
23
+ blue: string;
24
+ magenta: string;
25
+ cyan: string;
26
+ white: string;
27
+ gray: string;
28
+ bgBlack: string;
29
+ bgRed: string;
30
+ bgGreen: string;
31
+ bgYellow: string;
32
+ bgBlue: string;
33
+ bgMagenta: string;
34
+ bgCyan: string;
35
+ bgWhite: string;
36
+ brightBlack: string;
37
+ brightRed: string;
38
+ brightGreen: string;
39
+ brightYellow: string;
40
+ brightBlue: string;
41
+ brightMagenta: string;
42
+ brightCyan: string;
43
+ brightWhite: string;
44
+ };
45
+ export declare const symbols: {
46
+ dot: string;
47
+ check: string;
48
+ cross: string;
49
+ warning: string;
50
+ info: string;
51
+ arrowRight: string;
52
+ boxTopLeft: string;
53
+ boxTopRight: string;
54
+ boxBottomLeft: string;
55
+ boxBottomRight: string;
56
+ boxVertical: string;
57
+ boxHorizontal: string;
58
+ boxCross: string;
59
+ boxTLeft: string;
60
+ boxTRight: string;
61
+ barFull: string;
62
+ barEmpty: string;
63
+ barQuarter: string;
64
+ barHalf: string;
65
+ };
66
+ type ProgressBarOptions = {
67
+ total: number;
68
+ current: number;
69
+ width: number;
70
+ useAnsi: boolean;
71
+ label?: string;
72
+ suffix?: string;
73
+ };
74
+ export declare function renderProgressBar(options: ProgressBarOptions): string;
75
+ type BoxOptions = {
76
+ title?: string;
77
+ content: string[];
78
+ width?: number;
79
+ useAnsi: boolean;
80
+ showDivider?: boolean;
81
+ };
82
+ export declare function renderBox(options: BoxOptions): string;
83
+ export type ProgressRenderer = {
84
+ start: () => void;
85
+ update: (current: number, total: number, suffix?: string) => void;
86
+ finish: (message?: string) => void;
87
+ cleanup: () => void;
88
+ };
89
+ export declare function createProgressRenderer(label: string, useAnsi: boolean, isQuiet: boolean): ProgressRenderer;
90
+ export {};
91
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/infra/terminal.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,IAAI,YAAY,CAK9C;AAED,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,eAAO,MAAM,IAAI;;;sBAGE,MAAM;wBACJ,MAAM;uBACP,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCzB,CAAC;AAEF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;CAsBnB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAwBrE;AAED,KAAK,UAAU,GAAG;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CA4CrD;AAMD,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAClE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAiF1G"}