refine-mcp 0.1.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/dist/detection/compressor.d.ts +26 -0
- package/dist/detection/compressor.js +446 -0
- package/dist/detection/concern-map.d.ts +16 -0
- package/dist/detection/concern-map.js +236 -0
- package/dist/detection/context-extractor.d.ts +39 -0
- package/dist/detection/context-extractor.js +390 -0
- package/dist/detection/file-tree.d.ts +33 -0
- package/dist/detection/file-tree.js +174 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/prompts/index.d.ts +9 -0
- package/dist/prompts/index.js +125 -0
- package/dist/resources/identity.d.ts +6 -0
- package/dist/resources/identity.js +30 -0
- package/dist/resources/index.d.ts +6 -0
- package/dist/resources/index.js +14 -0
- package/dist/resources/prd.d.ts +6 -0
- package/dist/resources/prd.js +30 -0
- package/dist/resources/roadmap.d.ts +6 -0
- package/dist/resources/roadmap.js +30 -0
- package/dist/resources/tokens.d.ts +6 -0
- package/dist/resources/tokens.js +30 -0
- package/dist/setup.d.ts +11 -0
- package/dist/setup.js +429 -0
- package/dist/tools/checkin.d.ts +6 -0
- package/dist/tools/checkin.js +72 -0
- package/dist/tools/complete.d.ts +6 -0
- package/dist/tools/complete.js +56 -0
- package/dist/tools/get-prompt.d.ts +7 -0
- package/dist/tools/get-prompt.js +68 -0
- package/dist/tools/get-skill.d.ts +6 -0
- package/dist/tools/get-skill.js +57 -0
- package/dist/tools/refine-run.d.ts +22 -0
- package/dist/tools/refine-run.js +150 -0
- package/dist/utils/api.d.ts +12 -0
- package/dist/utils/api.js +69 -0
- package/dist/utils/config.d.ts +9 -0
- package/dist/utils/config.js +24 -0
- package/package.json +33 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regex-based code compressor — fallback quando concern map retorna > 50k tokens.
|
|
3
|
+
* Extrai assinaturas, tipos, exports e imports sem corpo de funcao.
|
|
4
|
+
* Zero dependencias externas. ~60-70% reducao de tokens.
|
|
5
|
+
*/
|
|
6
|
+
export interface CompressedFile {
|
|
7
|
+
path: string;
|
|
8
|
+
original_tokens: number;
|
|
9
|
+
compressed_tokens: number;
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CompressionResult {
|
|
13
|
+
files: CompressedFile[];
|
|
14
|
+
total_original_tokens: number;
|
|
15
|
+
total_compressed_tokens: number;
|
|
16
|
+
reduction_percent: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Comprime o conteudo de um arquivo baseado na extensao.
|
|
20
|
+
* Funcao pura — sem side effects, sem I/O.
|
|
21
|
+
*/
|
|
22
|
+
export declare function compressSource(source: string, filePath: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Comprime multiplos arquivos e retorna resultado agregado com metricas de tokens.
|
|
25
|
+
*/
|
|
26
|
+
export declare function compressFiles(filePaths: string[], cwd: string): Promise<CompressionResult>;
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regex-based code compressor — fallback quando concern map retorna > 50k tokens.
|
|
3
|
+
* Extrai assinaturas, tipos, exports e imports sem corpo de funcao.
|
|
4
|
+
* Zero dependencias externas. ~60-70% reducao de tokens.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { readFile } from "node:fs/promises";
|
|
8
|
+
import { extname, join } from "node:path";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Helpers
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
function estimateTokens(text) {
|
|
13
|
+
return Math.ceil(text.length / 4);
|
|
14
|
+
}
|
|
15
|
+
async function readFileOrNull(path) {
|
|
16
|
+
if (!existsSync(path))
|
|
17
|
+
return null;
|
|
18
|
+
try {
|
|
19
|
+
return await readFile(path, "utf-8");
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// TS/JS/TSX/JSX Compressor
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
function compressTypeScript(source) {
|
|
29
|
+
const lines = source.split("\n");
|
|
30
|
+
const output = [];
|
|
31
|
+
let depth = 0;
|
|
32
|
+
let inBlock = false;
|
|
33
|
+
let blockType = null;
|
|
34
|
+
let inExportType = false;
|
|
35
|
+
let exportTypeDepth = 0;
|
|
36
|
+
for (let i = 0; i < lines.length; i++) {
|
|
37
|
+
const line = lines[i];
|
|
38
|
+
const trimmed = line.trim();
|
|
39
|
+
// Skip empty lines inside blocks being compressed
|
|
40
|
+
if (inBlock && depth > 0) {
|
|
41
|
+
// Count braces on this line
|
|
42
|
+
for (const ch of line) {
|
|
43
|
+
if (ch === "{")
|
|
44
|
+
depth++;
|
|
45
|
+
if (ch === "}")
|
|
46
|
+
depth--;
|
|
47
|
+
}
|
|
48
|
+
if (depth <= 0) {
|
|
49
|
+
// Block closed — emit placeholder
|
|
50
|
+
depth = 0;
|
|
51
|
+
inBlock = false;
|
|
52
|
+
if (blockType === "internal-fn") {
|
|
53
|
+
output.push("// ... internal");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
output.push(" /* ... */ }");
|
|
57
|
+
}
|
|
58
|
+
blockType = null;
|
|
59
|
+
}
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// Track export interface / export type blocks (preserve fully)
|
|
63
|
+
if (inExportType) {
|
|
64
|
+
output.push(line);
|
|
65
|
+
for (const ch of line) {
|
|
66
|
+
if (ch === "{")
|
|
67
|
+
exportTypeDepth++;
|
|
68
|
+
if (ch === "}")
|
|
69
|
+
exportTypeDepth--;
|
|
70
|
+
}
|
|
71
|
+
if (exportTypeDepth <= 0) {
|
|
72
|
+
inExportType = false;
|
|
73
|
+
}
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// Blank lines — preserve between blocks
|
|
77
|
+
if (trimmed === "") {
|
|
78
|
+
output.push("");
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Import statements — preserve entirely
|
|
82
|
+
if (/^import\s/.test(trimmed) || /^import\s/.test(trimmed.replace(/^\/\/.*/, ""))) {
|
|
83
|
+
output.push(line);
|
|
84
|
+
// Handle multi-line imports
|
|
85
|
+
if (!trimmed.includes(";") && !trimmed.endsWith("'") && !trimmed.endsWith('"')) {
|
|
86
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
87
|
+
i = j;
|
|
88
|
+
output.push(lines[j]);
|
|
89
|
+
if (lines[j].includes(";") ||
|
|
90
|
+
lines[j].trim().endsWith("'") ||
|
|
91
|
+
lines[j].trim().endsWith('"'))
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// Export interface / export type — preserve fully
|
|
98
|
+
if (/^export\s+(interface|type)\s/.test(trimmed)) {
|
|
99
|
+
output.push(line);
|
|
100
|
+
// Single-line type alias
|
|
101
|
+
if (trimmed.includes(";") || (!trimmed.includes("{") && !trimmed.endsWith("{"))) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Multi-line — track brace depth
|
|
105
|
+
if (trimmed.includes("{")) {
|
|
106
|
+
inExportType = true;
|
|
107
|
+
exportTypeDepth = 0;
|
|
108
|
+
for (const ch of line) {
|
|
109
|
+
if (ch === "{")
|
|
110
|
+
exportTypeDepth++;
|
|
111
|
+
if (ch === "}")
|
|
112
|
+
exportTypeDepth--;
|
|
113
|
+
}
|
|
114
|
+
if (exportTypeDepth <= 0)
|
|
115
|
+
inExportType = false;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
inExportType = true;
|
|
119
|
+
exportTypeDepth = 0;
|
|
120
|
+
}
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// Re-exports: export { ... } from "..."
|
|
124
|
+
if (/^export\s*\{/.test(trimmed)) {
|
|
125
|
+
output.push(line);
|
|
126
|
+
if (!trimmed.includes("}")) {
|
|
127
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
128
|
+
i = j;
|
|
129
|
+
output.push(lines[j]);
|
|
130
|
+
if (lines[j].includes("}"))
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
// Export default
|
|
137
|
+
if (/^export\s+default\s/.test(trimmed)) {
|
|
138
|
+
output.push(line);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
// Exported function / async function / arrow function
|
|
142
|
+
if (/^export\s+(async\s+)?function\s/.test(trimmed) ||
|
|
143
|
+
/^export\s+const\s+\w+\s*=\s*(async\s+)?\(/.test(trimmed)) {
|
|
144
|
+
// Emit signature
|
|
145
|
+
const sigLine = line.replace(/\{[\s\S]*$/, "{").trimEnd();
|
|
146
|
+
output.push(sigLine.endsWith("{") ? sigLine : `${line.split("{")[0]}{`);
|
|
147
|
+
if (trimmed.includes("{")) {
|
|
148
|
+
blockType = "export-fn";
|
|
149
|
+
inBlock = true;
|
|
150
|
+
depth = 0;
|
|
151
|
+
for (const ch of line) {
|
|
152
|
+
if (ch === "{")
|
|
153
|
+
depth++;
|
|
154
|
+
if (ch === "}")
|
|
155
|
+
depth--;
|
|
156
|
+
}
|
|
157
|
+
if (depth <= 0) {
|
|
158
|
+
output.pop();
|
|
159
|
+
output.push(line.replace(/\{[\s\S]*\}/, "{ /* ... */ }"));
|
|
160
|
+
inBlock = false;
|
|
161
|
+
blockType = null;
|
|
162
|
+
depth = 0;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
// Exported class
|
|
168
|
+
if (/^export\s+(abstract\s+)?class\s/.test(trimmed)) {
|
|
169
|
+
output.push(line);
|
|
170
|
+
if (trimmed.includes("{")) {
|
|
171
|
+
// Parse class body — keep method signatures, skip bodies
|
|
172
|
+
blockType = "export-class";
|
|
173
|
+
inBlock = true;
|
|
174
|
+
depth = 0;
|
|
175
|
+
for (const ch of line) {
|
|
176
|
+
if (ch === "{")
|
|
177
|
+
depth++;
|
|
178
|
+
if (ch === "}")
|
|
179
|
+
depth--;
|
|
180
|
+
}
|
|
181
|
+
if (depth <= 0) {
|
|
182
|
+
inBlock = false;
|
|
183
|
+
blockType = null;
|
|
184
|
+
depth = 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
// Exported const/let/var (non-function)
|
|
190
|
+
if (/^export\s+(const|let|var)\s/.test(trimmed)) {
|
|
191
|
+
output.push(line);
|
|
192
|
+
// If multi-line value, skip until semicolon or balanced
|
|
193
|
+
if (!trimmed.includes(";") && trimmed.includes("{")) {
|
|
194
|
+
let valDepth = 0;
|
|
195
|
+
for (const ch of line) {
|
|
196
|
+
if (ch === "{")
|
|
197
|
+
valDepth++;
|
|
198
|
+
if (ch === "}")
|
|
199
|
+
valDepth--;
|
|
200
|
+
}
|
|
201
|
+
if (valDepth > 0) {
|
|
202
|
+
// Truncate — just show declaration
|
|
203
|
+
output.pop();
|
|
204
|
+
const declPart = line.split("=")[0];
|
|
205
|
+
output.push(`${declPart}= { /* ... */ };`);
|
|
206
|
+
// Skip until balanced
|
|
207
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
208
|
+
for (const ch of lines[j]) {
|
|
209
|
+
if (ch === "{")
|
|
210
|
+
valDepth++;
|
|
211
|
+
if (ch === "}")
|
|
212
|
+
valDepth--;
|
|
213
|
+
}
|
|
214
|
+
i = j;
|
|
215
|
+
if (valDepth <= 0)
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
// Internal (non-exported) function — replace with comment
|
|
223
|
+
if (/^(async\s+)?function\s/.test(trimmed) ||
|
|
224
|
+
/^const\s+\w+\s*=\s*(async\s+)?\(/.test(trimmed)) {
|
|
225
|
+
if (trimmed.includes("{")) {
|
|
226
|
+
blockType = "internal-fn";
|
|
227
|
+
inBlock = true;
|
|
228
|
+
depth = 0;
|
|
229
|
+
for (const ch of line) {
|
|
230
|
+
if (ch === "{")
|
|
231
|
+
depth++;
|
|
232
|
+
if (ch === "}")
|
|
233
|
+
depth--;
|
|
234
|
+
}
|
|
235
|
+
if (depth <= 0) {
|
|
236
|
+
output.push("// ... internal");
|
|
237
|
+
inBlock = false;
|
|
238
|
+
blockType = null;
|
|
239
|
+
depth = 0;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
// JSDoc at top of file (first block comment)
|
|
245
|
+
if (trimmed.startsWith("/**") && output.filter((l) => l.trim() !== "").length === 0) {
|
|
246
|
+
output.push(line);
|
|
247
|
+
if (!trimmed.endsWith("*/")) {
|
|
248
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
249
|
+
i = j;
|
|
250
|
+
output.push(lines[j]);
|
|
251
|
+
if (lines[j].trim().endsWith("*/"))
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
// Inline comments inside logic — skip
|
|
258
|
+
if (trimmed.startsWith("//")) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
// Decorators — preserve
|
|
262
|
+
if (trimmed.startsWith("@")) {
|
|
263
|
+
output.push(line);
|
|
264
|
+
}
|
|
265
|
+
// Everything else at top level — skip (implementation detail)
|
|
266
|
+
}
|
|
267
|
+
return output.join("\n");
|
|
268
|
+
}
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
// CSS Compressor
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
function compressCSS(source) {
|
|
273
|
+
const lines = source.split("\n");
|
|
274
|
+
const output = [];
|
|
275
|
+
let inRule = false;
|
|
276
|
+
let ruleDepth = 0;
|
|
277
|
+
let hasCustomProp = false;
|
|
278
|
+
let ruleLines = [];
|
|
279
|
+
for (const line of lines) {
|
|
280
|
+
const trimmed = line.trim();
|
|
281
|
+
// Preserve @import, @charset, @layer
|
|
282
|
+
if (/^@(import|charset|layer)\b/.test(trimmed)) {
|
|
283
|
+
output.push(line);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (inRule) {
|
|
287
|
+
for (const ch of line) {
|
|
288
|
+
if (ch === "{")
|
|
289
|
+
ruleDepth++;
|
|
290
|
+
if (ch === "}")
|
|
291
|
+
ruleDepth--;
|
|
292
|
+
}
|
|
293
|
+
// Check for custom properties
|
|
294
|
+
if (/^\s*--[\w-]+\s*:/.test(line)) {
|
|
295
|
+
hasCustomProp = true;
|
|
296
|
+
ruleLines.push(line);
|
|
297
|
+
}
|
|
298
|
+
if (ruleDepth <= 0) {
|
|
299
|
+
inRule = false;
|
|
300
|
+
if (hasCustomProp) {
|
|
301
|
+
// Emit selector + custom props only
|
|
302
|
+
for (const rl of ruleLines)
|
|
303
|
+
output.push(rl);
|
|
304
|
+
output.push("}");
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
output.push(" /* ... */ }");
|
|
308
|
+
}
|
|
309
|
+
ruleLines = [];
|
|
310
|
+
hasCustomProp = false;
|
|
311
|
+
}
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
// Blank line
|
|
315
|
+
if (trimmed === "") {
|
|
316
|
+
output.push("");
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
// Selector line (opens a rule block)
|
|
320
|
+
if (trimmed.endsWith("{") || trimmed.includes("{")) {
|
|
321
|
+
const selector = line.split("{")[0];
|
|
322
|
+
output.push(`${selector}{`);
|
|
323
|
+
ruleDepth = 0;
|
|
324
|
+
for (const ch of line) {
|
|
325
|
+
if (ch === "{")
|
|
326
|
+
ruleDepth++;
|
|
327
|
+
if (ch === "}")
|
|
328
|
+
ruleDepth--;
|
|
329
|
+
}
|
|
330
|
+
if (ruleDepth <= 0) {
|
|
331
|
+
// Single-line rule
|
|
332
|
+
if (/--[\w-]+\s*:/.test(line)) {
|
|
333
|
+
output.pop();
|
|
334
|
+
output.push(line);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
output.pop();
|
|
338
|
+
output.push(`${selector.trimEnd()} { /* ... */ }`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
inRule = true;
|
|
343
|
+
ruleLines = [];
|
|
344
|
+
hasCustomProp = false;
|
|
345
|
+
// Check if the opening line itself has a custom prop
|
|
346
|
+
if (/--[\w-]+\s*:/.test(line)) {
|
|
347
|
+
hasCustomProp = true;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
// Top-level custom property (outside any rule)
|
|
353
|
+
if (/^\s*--[\w-]+\s*:/.test(trimmed)) {
|
|
354
|
+
output.push(line);
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
output.push(line);
|
|
358
|
+
}
|
|
359
|
+
return output.join("\n");
|
|
360
|
+
}
|
|
361
|
+
// ---------------------------------------------------------------------------
|
|
362
|
+
// JSON Compressor
|
|
363
|
+
// ---------------------------------------------------------------------------
|
|
364
|
+
function compressJSON(source) {
|
|
365
|
+
try {
|
|
366
|
+
const parsed = JSON.parse(source);
|
|
367
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
368
|
+
return source;
|
|
369
|
+
const truncated = truncateDeep(parsed, 0, 2);
|
|
370
|
+
return JSON.stringify(truncated, null, 2);
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
return source;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
function truncateDeep(value, currentDepth, maxDepth) {
|
|
377
|
+
if (currentDepth >= maxDepth) {
|
|
378
|
+
if (Array.isArray(value))
|
|
379
|
+
return ["..."];
|
|
380
|
+
if (typeof value === "object" && value !== null)
|
|
381
|
+
return "...";
|
|
382
|
+
return value;
|
|
383
|
+
}
|
|
384
|
+
if (Array.isArray(value)) {
|
|
385
|
+
return value.map((item) => truncateDeep(item, currentDepth + 1, maxDepth));
|
|
386
|
+
}
|
|
387
|
+
if (typeof value === "object" && value !== null) {
|
|
388
|
+
const result = {};
|
|
389
|
+
for (const [key, val] of Object.entries(value)) {
|
|
390
|
+
result[key] = truncateDeep(val, currentDepth + 1, maxDepth);
|
|
391
|
+
}
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
394
|
+
return value;
|
|
395
|
+
}
|
|
396
|
+
// ---------------------------------------------------------------------------
|
|
397
|
+
// Public API
|
|
398
|
+
// ---------------------------------------------------------------------------
|
|
399
|
+
const TS_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx"]);
|
|
400
|
+
/**
|
|
401
|
+
* Comprime o conteudo de um arquivo baseado na extensao.
|
|
402
|
+
* Funcao pura — sem side effects, sem I/O.
|
|
403
|
+
*/
|
|
404
|
+
export function compressSource(source, filePath) {
|
|
405
|
+
const ext = extname(filePath).toLowerCase();
|
|
406
|
+
if (TS_EXTENSIONS.has(ext))
|
|
407
|
+
return compressTypeScript(source);
|
|
408
|
+
if (ext === ".css")
|
|
409
|
+
return compressCSS(source);
|
|
410
|
+
if (ext === ".json")
|
|
411
|
+
return compressJSON(source);
|
|
412
|
+
// Extensao desconhecida — retorna original
|
|
413
|
+
return source;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Comprime multiplos arquivos e retorna resultado agregado com metricas de tokens.
|
|
417
|
+
*/
|
|
418
|
+
export async function compressFiles(filePaths, cwd) {
|
|
419
|
+
const files = [];
|
|
420
|
+
let totalOriginal = 0;
|
|
421
|
+
let totalCompressed = 0;
|
|
422
|
+
for (const filePath of filePaths) {
|
|
423
|
+
const fullPath = join(cwd, filePath);
|
|
424
|
+
const content = await readFileOrNull(fullPath);
|
|
425
|
+
if (content === null)
|
|
426
|
+
continue;
|
|
427
|
+
const originalTokens = estimateTokens(content);
|
|
428
|
+
const compressed = compressSource(content, filePath);
|
|
429
|
+
const compressedTokens = estimateTokens(compressed);
|
|
430
|
+
totalOriginal += originalTokens;
|
|
431
|
+
totalCompressed += compressedTokens;
|
|
432
|
+
files.push({
|
|
433
|
+
path: filePath,
|
|
434
|
+
original_tokens: originalTokens,
|
|
435
|
+
compressed_tokens: compressedTokens,
|
|
436
|
+
content: compressed,
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
const reductionPercent = totalOriginal > 0 ? Math.round(((totalOriginal - totalCompressed) / totalOriginal) * 100) : 0;
|
|
440
|
+
return {
|
|
441
|
+
files,
|
|
442
|
+
total_original_tokens: totalOriginal,
|
|
443
|
+
total_compressed_tokens: totalCompressed,
|
|
444
|
+
reduction_percent: reductionPercent,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Concern Map — regras determinísticas de seleção de arquivos por tipo de refine.
|
|
3
|
+
* Zero tokens de LLM. Cada tipo de refine tem patterns genéricos + stack-specific.
|
|
4
|
+
*/
|
|
5
|
+
export type RefineType = string;
|
|
6
|
+
export type StackDatabase = "convex" | "supabase" | "prisma" | "drizzle" | "firebase" | "django" | "unknown";
|
|
7
|
+
export interface ConcernMapResult {
|
|
8
|
+
files: string[];
|
|
9
|
+
patterns: string[];
|
|
10
|
+
stack: StackDatabase;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Seleciona arquivos relevantes para um tipo de refine, baseado em patterns
|
|
14
|
+
* determinísticos (genéricos + stack-specific).
|
|
15
|
+
*/
|
|
16
|
+
export declare function selectFiles(refineType: string, stack: StackDatabase, cwd: string): Promise<ConcernMapResult>;
|