codesummary 1.0.2 ā 1.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/CHANGELOG.md +166 -0
- package/README.md +242 -51
- package/bin/codesummary.js +12 -12
- package/package.json +96 -84
- package/rag-schema.json +114 -0
- package/src/cli.js +509 -391
- package/src/configManager.js +827 -427
- package/src/errorHandler.js +477 -342
- package/src/index.js +25 -25
- package/src/pdfGenerator.js +475 -426
- package/src/ragConfig.js +373 -0
- package/src/ragGenerator.js +1758 -0
- package/src/scanner.js +467 -329
- package/RELEASE.md +0 -412
package/src/configManager.js
CHANGED
|
@@ -1,427 +1,827 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import ErrorHandler from
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Configuration Manager for CodeSummary
|
|
10
|
-
* Handles global configuration storage, first-run setup, and user preferences
|
|
11
|
-
* Cross-platform compatible with POSIX and Windows systems
|
|
12
|
-
*/
|
|
13
|
-
export class ConfigManager {
|
|
14
|
-
constructor() {
|
|
15
|
-
this.configDir = this.getConfigDirectory();
|
|
16
|
-
this.configPath = path.join(this.configDir,
|
|
17
|
-
this.defaultConfig = this.getDefaultConfig();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Get the appropriate configuration directory based on platform
|
|
22
|
-
* @returns {string} Configuration directory path
|
|
23
|
-
*/
|
|
24
|
-
getConfigDirectory() {
|
|
25
|
-
const platform = os.platform();
|
|
26
|
-
const homeDir = os.homedir();
|
|
27
|
-
|
|
28
|
-
if (platform ===
|
|
29
|
-
// Windows: %APPDATA%\CodeSummary\
|
|
30
|
-
return path.join(process.env.APPDATA || homeDir,
|
|
31
|
-
} else {
|
|
32
|
-
// POSIX (Linux/macOS): ~/.codesummary/
|
|
33
|
-
return path.join(homeDir,
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get default configuration object
|
|
39
|
-
* @returns {object} Default configuration
|
|
40
|
-
*/
|
|
41
|
-
getDefaultConfig() {
|
|
42
|
-
return {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
{
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import inquirer from "inquirer";
|
|
4
|
+
import os from "os";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import ErrorHandler from "./errorHandler.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Configuration Manager for CodeSummary
|
|
10
|
+
* Handles global configuration storage, first-run setup, and user preferences
|
|
11
|
+
* Cross-platform compatible with POSIX and Windows systems
|
|
12
|
+
*/
|
|
13
|
+
export class ConfigManager {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.configDir = this.getConfigDirectory();
|
|
16
|
+
this.configPath = path.join(this.configDir, "config.json");
|
|
17
|
+
this.defaultConfig = this.getDefaultConfig();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the appropriate configuration directory based on platform
|
|
22
|
+
* @returns {string} Configuration directory path
|
|
23
|
+
*/
|
|
24
|
+
getConfigDirectory() {
|
|
25
|
+
const platform = os.platform();
|
|
26
|
+
const homeDir = os.homedir();
|
|
27
|
+
|
|
28
|
+
if (platform === "win32") {
|
|
29
|
+
// Windows: %APPDATA%\CodeSummary\
|
|
30
|
+
return path.join(process.env.APPDATA || homeDir, "CodeSummary");
|
|
31
|
+
} else {
|
|
32
|
+
// POSIX (Linux/macOS): ~/.codesummary/
|
|
33
|
+
return path.join(homeDir, ".codesummary");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get default configuration object
|
|
39
|
+
* @returns {object} Default configuration
|
|
40
|
+
*/
|
|
41
|
+
getDefaultConfig() {
|
|
42
|
+
return {
|
|
43
|
+
configVersion: "1.1.0", // Version tracking for migrations
|
|
44
|
+
output: {
|
|
45
|
+
mode: "fixed",
|
|
46
|
+
fixedPath: path.join(os.homedir(), "Desktop", "CodeSummaries"),
|
|
47
|
+
},
|
|
48
|
+
allowedExtensions: [
|
|
49
|
+
".json",
|
|
50
|
+
".ts",
|
|
51
|
+
".js",
|
|
52
|
+
".jsx",
|
|
53
|
+
".tsx",
|
|
54
|
+
".xml",
|
|
55
|
+
".html",
|
|
56
|
+
".css",
|
|
57
|
+
".scss",
|
|
58
|
+
".md",
|
|
59
|
+
".txt",
|
|
60
|
+
".py",
|
|
61
|
+
".java",
|
|
62
|
+
".cs",
|
|
63
|
+
".cpp",
|
|
64
|
+
".c",
|
|
65
|
+
".h",
|
|
66
|
+
".yaml",
|
|
67
|
+
".yml",
|
|
68
|
+
".sh",
|
|
69
|
+
".bat",
|
|
70
|
+
],
|
|
71
|
+
excludeDirs: [
|
|
72
|
+
"node_modules",
|
|
73
|
+
".git",
|
|
74
|
+
".vscode",
|
|
75
|
+
"dist",
|
|
76
|
+
"build",
|
|
77
|
+
"coverage",
|
|
78
|
+
"out",
|
|
79
|
+
"__pycache__",
|
|
80
|
+
".next",
|
|
81
|
+
".nuxt",
|
|
82
|
+
],
|
|
83
|
+
excludeFiles: [
|
|
84
|
+
"*-lock.json", // package-lock.json, yarn.lock, etc.
|
|
85
|
+
"*.lock", // Cargo.lock, Gemfile.lock, etc.
|
|
86
|
+
"composer.lock", // PHP Composer lock
|
|
87
|
+
"Pipfile.lock", // Python Pipfile lock
|
|
88
|
+
"*.min.js", // Minified JavaScript
|
|
89
|
+
"*.min.css", // Minified CSS
|
|
90
|
+
"*.map", // Source maps
|
|
91
|
+
".DS_Store", // macOS metadata
|
|
92
|
+
"Thumbs.db", // Windows thumbnail cache
|
|
93
|
+
"*-lock.yaml", // YAML lock files
|
|
94
|
+
],
|
|
95
|
+
styles: {
|
|
96
|
+
colors: {
|
|
97
|
+
title: "#333353",
|
|
98
|
+
section: "#00FFB9",
|
|
99
|
+
text: "#333333",
|
|
100
|
+
error: "#FF4D4D",
|
|
101
|
+
footer: "#666666",
|
|
102
|
+
},
|
|
103
|
+
layout: {
|
|
104
|
+
marginLeft: 40,
|
|
105
|
+
marginTop: 40,
|
|
106
|
+
marginRight: 40,
|
|
107
|
+
footerHeight: 20,
|
|
108
|
+
},
|
|
109
|
+
fonts: {
|
|
110
|
+
base: "Source Code Pro",
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
settings: {
|
|
114
|
+
documentTitle: "Project Code Summary",
|
|
115
|
+
maxFilesBeforePrompt: 500,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if configuration file exists
|
|
122
|
+
* @returns {boolean} True if config exists
|
|
123
|
+
*/
|
|
124
|
+
configExists() {
|
|
125
|
+
return fs.existsSync(this.configPath);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Load configuration from file or return null if not found/corrupted
|
|
130
|
+
* @returns {object|null} Configuration object or null
|
|
131
|
+
*/
|
|
132
|
+
async loadConfig() {
|
|
133
|
+
try {
|
|
134
|
+
if (!this.configExists()) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const configData = await fs.readJSON(this.configPath);
|
|
139
|
+
|
|
140
|
+
// Migrate configuration if needed (add missing fields)
|
|
141
|
+
const migratedConfig = this.migrateConfig(configData);
|
|
142
|
+
|
|
143
|
+
// Validate configuration structure
|
|
144
|
+
ErrorHandler.validateConfig(migratedConfig);
|
|
145
|
+
|
|
146
|
+
// Save migrated config back if it was changed
|
|
147
|
+
if (JSON.stringify(configData) !== JSON.stringify(migratedConfig)) {
|
|
148
|
+
await this.saveConfig(migratedConfig);
|
|
149
|
+
|
|
150
|
+
// Show user-friendly notification about what was updated
|
|
151
|
+
if (this._pendingNotification) {
|
|
152
|
+
await this.notifyConfigUpdates(
|
|
153
|
+
this._pendingNotification.newExclusions,
|
|
154
|
+
this._pendingNotification.newDirs,
|
|
155
|
+
this._pendingNotification.newExtensions
|
|
156
|
+
);
|
|
157
|
+
this._pendingNotification = null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return migratedConfig;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (error.code === "ENOENT") {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (error.message.includes("JSON")) {
|
|
168
|
+
console.log(
|
|
169
|
+
chalk.red("ERROR: Configuration file contains invalid JSON.")
|
|
170
|
+
);
|
|
171
|
+
} else if (error.message.includes("Configuration")) {
|
|
172
|
+
console.log(
|
|
173
|
+
chalk.red("ERROR: Configuration file structure is invalid.")
|
|
174
|
+
);
|
|
175
|
+
console.log(chalk.gray("Details:"), error.message);
|
|
176
|
+
} else {
|
|
177
|
+
ErrorHandler.handleFileSystemError(
|
|
178
|
+
error,
|
|
179
|
+
"read configuration",
|
|
180
|
+
this.configPath
|
|
181
|
+
);
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const { shouldReset } = await inquirer.prompt([
|
|
186
|
+
{
|
|
187
|
+
type: "confirm",
|
|
188
|
+
name: "shouldReset",
|
|
189
|
+
message: "Do you want to reset the configuration?",
|
|
190
|
+
default: true,
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
|
|
194
|
+
if (shouldReset) {
|
|
195
|
+
await this.resetConfig();
|
|
196
|
+
return await this.runFirstTimeSetup();
|
|
197
|
+
} else {
|
|
198
|
+
await ErrorHandler.safeExit(1, "Configuration setup cancelled");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Save configuration to file
|
|
205
|
+
* @param {object} config Configuration object to save
|
|
206
|
+
*/
|
|
207
|
+
async saveConfig(config) {
|
|
208
|
+
try {
|
|
209
|
+
// Validate configuration before saving
|
|
210
|
+
ErrorHandler.validateConfig(config);
|
|
211
|
+
|
|
212
|
+
// Ensure config directory exists
|
|
213
|
+
await fs.ensureDir(this.configDir);
|
|
214
|
+
|
|
215
|
+
// Save configuration with pretty formatting
|
|
216
|
+
await fs.writeJSON(this.configPath, config, { spaces: 2 });
|
|
217
|
+
|
|
218
|
+
console.log(chalk.green(`Configuration saved to ${this.configPath}`));
|
|
219
|
+
} catch (error) {
|
|
220
|
+
if (error.message.includes("Configuration")) {
|
|
221
|
+
console.error(
|
|
222
|
+
chalk.red("ERROR: Invalid configuration:"),
|
|
223
|
+
error.message
|
|
224
|
+
);
|
|
225
|
+
} else {
|
|
226
|
+
ErrorHandler.handleFileSystemError(
|
|
227
|
+
error,
|
|
228
|
+
"save configuration",
|
|
229
|
+
this.configPath
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
await ErrorHandler.safeExit(1, "Configuration save failed");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Smart merge arrays preserving user customizations while adding new defaults
|
|
238
|
+
* @param {Array} userArray - User's current array
|
|
239
|
+
* @param {Array} defaultArray - New default array
|
|
240
|
+
* @returns {object} Object with merged array and new items
|
|
241
|
+
*/
|
|
242
|
+
smartMergeArrays(userArray, defaultArray) {
|
|
243
|
+
if (!Array.isArray(userArray)) userArray = [];
|
|
244
|
+
if (!Array.isArray(defaultArray)) defaultArray = [];
|
|
245
|
+
|
|
246
|
+
// Find new items that user doesn't have
|
|
247
|
+
const newItems = defaultArray.filter(item => !userArray.includes(item));
|
|
248
|
+
|
|
249
|
+
// Combine arrays removing duplicates, preserving user's order first
|
|
250
|
+
const merged = [...userArray, ...newItems];
|
|
251
|
+
|
|
252
|
+
return { merged, newItems };
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Show user-friendly notification about configuration updates
|
|
257
|
+
* @param {Array} newExclusions - New exclusion patterns added
|
|
258
|
+
* @param {Array} newDirs - New directories added
|
|
259
|
+
* @param {Array} newExtensions - New extensions added
|
|
260
|
+
*/
|
|
261
|
+
async notifyConfigUpdates(newExclusions = [], newDirs = [], newExtensions = []) {
|
|
262
|
+
if (newExclusions.length === 0 && newDirs.length === 0 && newExtensions.length === 0) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
console.log(chalk.cyan("\nš Configuration Updated"));
|
|
267
|
+
console.log(chalk.gray("New items have been added to improve file scanning:\n"));
|
|
268
|
+
|
|
269
|
+
if (newExclusions.length > 0) {
|
|
270
|
+
console.log(chalk.green("ā New file patterns to skip:"));
|
|
271
|
+
newExclusions.forEach(pattern => {
|
|
272
|
+
console.log(chalk.gray(` ⢠${pattern} (saves processing time)`));
|
|
273
|
+
});
|
|
274
|
+
console.log();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (newDirs.length > 0) {
|
|
278
|
+
console.log(chalk.green("ā New directories to skip:"));
|
|
279
|
+
newDirs.forEach(dir => {
|
|
280
|
+
console.log(chalk.gray(` ⢠${dir}/ (improves performance)`));
|
|
281
|
+
});
|
|
282
|
+
console.log();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (newExtensions.length > 0) {
|
|
286
|
+
console.log(chalk.green("ā New file types to include:"));
|
|
287
|
+
newExtensions.forEach(ext => {
|
|
288
|
+
console.log(chalk.gray(` ⢠*${ext} files`));
|
|
289
|
+
});
|
|
290
|
+
console.log();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log(chalk.gray("Your custom settings have been preserved! āØ\n"));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Migrate old configuration to new format with intelligent merging
|
|
298
|
+
* @param {object} oldConfig - Old configuration object
|
|
299
|
+
* @returns {object} Migrated configuration
|
|
300
|
+
*/
|
|
301
|
+
migrateConfig(oldConfig) {
|
|
302
|
+
const defaultConfig = this.getDefaultConfig();
|
|
303
|
+
const migratedConfig = { ...oldConfig };
|
|
304
|
+
|
|
305
|
+
// Track what's new for user notification
|
|
306
|
+
let newExclusions = [];
|
|
307
|
+
let newDirs = [];
|
|
308
|
+
let newExtensions = [];
|
|
309
|
+
|
|
310
|
+
// Add config version if missing
|
|
311
|
+
if (!migratedConfig.configVersion) {
|
|
312
|
+
migratedConfig.configVersion = defaultConfig.configVersion;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Smart merge for excludeFiles
|
|
316
|
+
if (migratedConfig.excludeFiles) {
|
|
317
|
+
const { merged, newItems } = this.smartMergeArrays(
|
|
318
|
+
migratedConfig.excludeFiles,
|
|
319
|
+
defaultConfig.excludeFiles
|
|
320
|
+
);
|
|
321
|
+
migratedConfig.excludeFiles = merged;
|
|
322
|
+
newExclusions = newItems;
|
|
323
|
+
} else {
|
|
324
|
+
migratedConfig.excludeFiles = defaultConfig.excludeFiles;
|
|
325
|
+
newExclusions = defaultConfig.excludeFiles;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Smart merge for excludeDirs
|
|
329
|
+
if (migratedConfig.excludeDirs) {
|
|
330
|
+
const { merged, newItems } = this.smartMergeArrays(
|
|
331
|
+
migratedConfig.excludeDirs,
|
|
332
|
+
defaultConfig.excludeDirs
|
|
333
|
+
);
|
|
334
|
+
migratedConfig.excludeDirs = merged;
|
|
335
|
+
newDirs = newItems;
|
|
336
|
+
} else {
|
|
337
|
+
migratedConfig.excludeDirs = defaultConfig.excludeDirs;
|
|
338
|
+
newDirs = defaultConfig.excludeDirs;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Smart merge for allowedExtensions
|
|
342
|
+
if (migratedConfig.allowedExtensions) {
|
|
343
|
+
const { merged, newItems } = this.smartMergeArrays(
|
|
344
|
+
migratedConfig.allowedExtensions,
|
|
345
|
+
defaultConfig.allowedExtensions
|
|
346
|
+
);
|
|
347
|
+
migratedConfig.allowedExtensions = merged;
|
|
348
|
+
newExtensions = newItems;
|
|
349
|
+
} else {
|
|
350
|
+
migratedConfig.allowedExtensions = defaultConfig.allowedExtensions;
|
|
351
|
+
newExtensions = defaultConfig.allowedExtensions;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Add any other missing scalar fields from defaults
|
|
355
|
+
Object.keys(defaultConfig).forEach((key) => {
|
|
356
|
+
if (!migratedConfig.hasOwnProperty(key) && !Array.isArray(defaultConfig[key])) {
|
|
357
|
+
migratedConfig[key] = defaultConfig[key];
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// Show user-friendly notification about updates (will be called by loadConfig)
|
|
362
|
+
this._pendingNotification = { newExclusions, newDirs, newExtensions };
|
|
363
|
+
|
|
364
|
+
return migratedConfig;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Delete existing configuration file
|
|
369
|
+
*/
|
|
370
|
+
async resetConfig() {
|
|
371
|
+
try {
|
|
372
|
+
if (this.configExists()) {
|
|
373
|
+
await fs.remove(this.configPath);
|
|
374
|
+
console.log(chalk.yellow("Configuration reset successfully."));
|
|
375
|
+
}
|
|
376
|
+
} catch (error) {
|
|
377
|
+
console.error(
|
|
378
|
+
chalk.red("ERROR: Failed to reset configuration:"),
|
|
379
|
+
error.message
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Run the first-time setup wizard
|
|
386
|
+
* @returns {object} New configuration object
|
|
387
|
+
*/
|
|
388
|
+
async runFirstTimeSetup() {
|
|
389
|
+
console.log(chalk.cyan("Welcome to CodeSummary!"));
|
|
390
|
+
console.log(chalk.gray("No configuration found. Starting setup...\n"));
|
|
391
|
+
|
|
392
|
+
const answers = await inquirer.prompt([
|
|
393
|
+
{
|
|
394
|
+
type: "list",
|
|
395
|
+
name: "outputMode",
|
|
396
|
+
message: "Where should the PDF be generated by default?",
|
|
397
|
+
choices: [
|
|
398
|
+
{
|
|
399
|
+
name: "Current working directory (relative mode)",
|
|
400
|
+
value: "relative",
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
name: "Fixed folder (absolute mode)",
|
|
404
|
+
value: "fixed",
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
default: "fixed",
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
type: "input",
|
|
411
|
+
name: "fixedPath",
|
|
412
|
+
message: "Enter absolute path for fixed folder:",
|
|
413
|
+
default: path.join(os.homedir(), "Desktop", "CodeSummaries"),
|
|
414
|
+
when: (answers) => answers.outputMode === "fixed",
|
|
415
|
+
validate: (input) => {
|
|
416
|
+
if (!path.isAbsolute(input)) {
|
|
417
|
+
return "Please enter an absolute path";
|
|
418
|
+
}
|
|
419
|
+
return true;
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
]);
|
|
423
|
+
|
|
424
|
+
// Create the config object
|
|
425
|
+
const config = { ...this.defaultConfig };
|
|
426
|
+
config.output.mode = answers.outputMode;
|
|
427
|
+
|
|
428
|
+
if (answers.outputMode === "fixed") {
|
|
429
|
+
config.output.fixedPath = path.resolve(answers.fixedPath);
|
|
430
|
+
|
|
431
|
+
// Atomically ensure directory exists
|
|
432
|
+
try {
|
|
433
|
+
// Use ensureDir which is atomic and handles race conditions
|
|
434
|
+
await fs.ensureDir(config.output.fixedPath);
|
|
435
|
+
|
|
436
|
+
// Verify the directory was created and is accessible
|
|
437
|
+
const stats = await fs.stat(config.output.fixedPath);
|
|
438
|
+
if (!stats.isDirectory()) {
|
|
439
|
+
throw new Error("Path exists but is not a directory");
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Test write permissions
|
|
443
|
+
const testFile = path.join(config.output.fixedPath, ".write-test");
|
|
444
|
+
try {
|
|
445
|
+
await fs.writeFile(testFile, "test");
|
|
446
|
+
await fs.remove(testFile);
|
|
447
|
+
} catch (writeError) {
|
|
448
|
+
throw new Error(`Directory not writable: ${writeError.message}`);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
console.log(
|
|
452
|
+
chalk.green(
|
|
453
|
+
`SUCCESS: Output directory ready: ${config.output.fixedPath}`
|
|
454
|
+
)
|
|
455
|
+
);
|
|
456
|
+
} catch (error) {
|
|
457
|
+
// If directory creation fails, ask user for confirmation
|
|
458
|
+
console.log(
|
|
459
|
+
chalk.yellow(
|
|
460
|
+
`WARNING: Could not prepare output directory: ${error.message}`
|
|
461
|
+
)
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
const { createDir } = await inquirer.prompt([
|
|
465
|
+
{
|
|
466
|
+
type: "confirm",
|
|
467
|
+
name: "createDir",
|
|
468
|
+
message: `Try to create directory ${config.output.fixedPath} anyway?`,
|
|
469
|
+
default: true,
|
|
470
|
+
},
|
|
471
|
+
]);
|
|
472
|
+
|
|
473
|
+
if (createDir) {
|
|
474
|
+
try {
|
|
475
|
+
// Force creation with more permissive mode
|
|
476
|
+
await fs.ensureDir(config.output.fixedPath, { mode: 0o755 });
|
|
477
|
+
console.log(
|
|
478
|
+
chalk.green(
|
|
479
|
+
`SUCCESS: Created directory: ${config.output.fixedPath}`
|
|
480
|
+
)
|
|
481
|
+
);
|
|
482
|
+
} catch (retryError) {
|
|
483
|
+
console.error(
|
|
484
|
+
chalk.red("ERROR: Failed to create directory:"),
|
|
485
|
+
retryError.message
|
|
486
|
+
);
|
|
487
|
+
await ErrorHandler.safeExit(1, "Directory creation failed");
|
|
488
|
+
}
|
|
489
|
+
} else {
|
|
490
|
+
console.log(
|
|
491
|
+
chalk.yellow(
|
|
492
|
+
"WARNING: Continuing without creating directory. PDF generation may fail."
|
|
493
|
+
)
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Save the configuration
|
|
500
|
+
await this.saveConfig(config);
|
|
501
|
+
|
|
502
|
+
console.log(chalk.green("\nSUCCESS: Setup completed successfully!\n"));
|
|
503
|
+
|
|
504
|
+
return config;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Launch interactive configuration editor
|
|
509
|
+
* @param {object} currentConfig Current configuration to edit
|
|
510
|
+
* @returns {object} Updated configuration
|
|
511
|
+
*/
|
|
512
|
+
async editConfig(currentConfig) {
|
|
513
|
+
console.log(chalk.cyan("Configuration Editor\n"));
|
|
514
|
+
|
|
515
|
+
const choices = [
|
|
516
|
+
"Output Settings",
|
|
517
|
+
"File Extensions",
|
|
518
|
+
"Excluded Directories",
|
|
519
|
+
"Excluded Files",
|
|
520
|
+
"PDF Styling",
|
|
521
|
+
"General Settings",
|
|
522
|
+
"Save and Exit",
|
|
523
|
+
];
|
|
524
|
+
|
|
525
|
+
let config = { ...currentConfig };
|
|
526
|
+
let editing = true;
|
|
527
|
+
|
|
528
|
+
while (editing) {
|
|
529
|
+
const { section } = await inquirer.prompt([
|
|
530
|
+
{
|
|
531
|
+
type: "list",
|
|
532
|
+
name: "section",
|
|
533
|
+
message: "Select section to edit:",
|
|
534
|
+
choices,
|
|
535
|
+
},
|
|
536
|
+
]);
|
|
537
|
+
|
|
538
|
+
switch (section) {
|
|
539
|
+
case "Output Settings":
|
|
540
|
+
config = await this.editOutputSettings(config);
|
|
541
|
+
break;
|
|
542
|
+
case "File Extensions":
|
|
543
|
+
config = await this.editAllowedExtensions(config);
|
|
544
|
+
break;
|
|
545
|
+
case "Excluded Directories":
|
|
546
|
+
config = await this.editExcludedDirs(config);
|
|
547
|
+
break;
|
|
548
|
+
case "Excluded Files":
|
|
549
|
+
config = await this.editExcludedFiles(config);
|
|
550
|
+
break;
|
|
551
|
+
case "PDF Styling":
|
|
552
|
+
console.log(
|
|
553
|
+
chalk.yellow("PDF styling editor coming in future version")
|
|
554
|
+
);
|
|
555
|
+
break;
|
|
556
|
+
case "General Settings":
|
|
557
|
+
config = await this.editGeneralSettings(config);
|
|
558
|
+
break;
|
|
559
|
+
case "Save and Exit":
|
|
560
|
+
editing = false;
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
await this.saveConfig(config);
|
|
566
|
+
return config;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Edit output settings
|
|
571
|
+
* @param {object} config Current configuration
|
|
572
|
+
* @returns {object} Updated configuration
|
|
573
|
+
*/
|
|
574
|
+
async editOutputSettings(config) {
|
|
575
|
+
const answers = await inquirer.prompt([
|
|
576
|
+
{
|
|
577
|
+
type: "list",
|
|
578
|
+
name: "mode",
|
|
579
|
+
message: "Output mode:",
|
|
580
|
+
choices: [
|
|
581
|
+
{ name: "Relative (current directory)", value: "relative" },
|
|
582
|
+
{ name: "Fixed path", value: "fixed" },
|
|
583
|
+
],
|
|
584
|
+
default: config.output.mode,
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
type: "input",
|
|
588
|
+
name: "fixedPath",
|
|
589
|
+
message: "Fixed path:",
|
|
590
|
+
default: config.output.fixedPath,
|
|
591
|
+
when: (answers) => answers.mode === "fixed",
|
|
592
|
+
},
|
|
593
|
+
]);
|
|
594
|
+
|
|
595
|
+
config.output.mode = answers.mode;
|
|
596
|
+
if (answers.fixedPath) {
|
|
597
|
+
config.output.fixedPath = path.resolve(answers.fixedPath);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return config;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Edit allowed extensions
|
|
605
|
+
* @param {object} config Current configuration
|
|
606
|
+
* @returns {object} Updated configuration
|
|
607
|
+
*/
|
|
608
|
+
async editAllowedExtensions(config) {
|
|
609
|
+
const { extensions } = await inquirer.prompt([
|
|
610
|
+
{
|
|
611
|
+
type: "input",
|
|
612
|
+
name: "extensions",
|
|
613
|
+
message: "Allowed extensions (comma-separated):",
|
|
614
|
+
default: config.allowedExtensions.join(", "),
|
|
615
|
+
validate: (input) => {
|
|
616
|
+
if (!input.trim()) {
|
|
617
|
+
return "Please enter at least one extension";
|
|
618
|
+
}
|
|
619
|
+
return true;
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
]);
|
|
623
|
+
|
|
624
|
+
config.allowedExtensions = extensions
|
|
625
|
+
.split(",")
|
|
626
|
+
.map((ext) => ext.trim())
|
|
627
|
+
.filter((ext) => ext.length > 0)
|
|
628
|
+
.map((ext) => (ext.startsWith(".") ? ext : "." + ext));
|
|
629
|
+
|
|
630
|
+
return config;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Edit excluded directories
|
|
635
|
+
* @param {object} config Current configuration
|
|
636
|
+
* @returns {object} Updated configuration
|
|
637
|
+
*/
|
|
638
|
+
async editExcludedDirs(config) {
|
|
639
|
+
const { dirs } = await inquirer.prompt([
|
|
640
|
+
{
|
|
641
|
+
type: "input",
|
|
642
|
+
name: "dirs",
|
|
643
|
+
message: "Excluded directories (comma-separated):",
|
|
644
|
+
default: config.excludeDirs.join(", "),
|
|
645
|
+
},
|
|
646
|
+
]);
|
|
647
|
+
|
|
648
|
+
config.excludeDirs = dirs
|
|
649
|
+
.split(",")
|
|
650
|
+
.map((dir) => dir.trim())
|
|
651
|
+
.filter((dir) => dir.length > 0);
|
|
652
|
+
|
|
653
|
+
return config;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Edit excluded files patterns
|
|
658
|
+
* @param {object} config Current configuration
|
|
659
|
+
* @returns {object} Updated configuration
|
|
660
|
+
*/
|
|
661
|
+
async editExcludedFiles(config) {
|
|
662
|
+
// Ensure excludeFiles exists for backward compatibility
|
|
663
|
+
if (!config.excludeFiles) {
|
|
664
|
+
config.excludeFiles = [
|
|
665
|
+
"*-lock.json",
|
|
666
|
+
"*.lock",
|
|
667
|
+
"composer.lock",
|
|
668
|
+
"Pipfile.lock",
|
|
669
|
+
"*.min.js",
|
|
670
|
+
"*.min.css",
|
|
671
|
+
"*.map",
|
|
672
|
+
".DS_Store",
|
|
673
|
+
"Thumbs.db",
|
|
674
|
+
];
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const { files } = await inquirer.prompt([
|
|
678
|
+
{
|
|
679
|
+
type: "input",
|
|
680
|
+
name: "files",
|
|
681
|
+
message:
|
|
682
|
+
"Excluded file patterns (comma-separated, supports * wildcards):",
|
|
683
|
+
default: config.excludeFiles.join(", "),
|
|
684
|
+
validate: (input) => {
|
|
685
|
+
if (!input.trim()) {
|
|
686
|
+
return "Enter file patterns or leave empty to clear all exclusions";
|
|
687
|
+
}
|
|
688
|
+
return true;
|
|
689
|
+
},
|
|
690
|
+
},
|
|
691
|
+
]);
|
|
692
|
+
|
|
693
|
+
if (files.trim()) {
|
|
694
|
+
config.excludeFiles = files
|
|
695
|
+
.split(",")
|
|
696
|
+
.map((pattern) => pattern.trim())
|
|
697
|
+
.filter((pattern) => pattern.length > 0);
|
|
698
|
+
} else {
|
|
699
|
+
config.excludeFiles = [];
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
console.log(
|
|
703
|
+
chalk.green(
|
|
704
|
+
`\nā Updated excluded files: ${config.excludeFiles.length} patterns`
|
|
705
|
+
)
|
|
706
|
+
);
|
|
707
|
+
if (config.excludeFiles.length > 0) {
|
|
708
|
+
console.log(chalk.gray(" Examples of files that will be excluded:"));
|
|
709
|
+
config.excludeFiles.slice(0, 3).forEach((pattern) => {
|
|
710
|
+
console.log(chalk.gray(` - ${pattern}`));
|
|
711
|
+
});
|
|
712
|
+
if (config.excludeFiles.length > 3) {
|
|
713
|
+
console.log(
|
|
714
|
+
chalk.gray(` ... and ${config.excludeFiles.length - 3} more`)
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return config;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Edit general settings
|
|
724
|
+
* @param {object} config Current configuration
|
|
725
|
+
* @returns {object} Updated configuration
|
|
726
|
+
*/
|
|
727
|
+
async editGeneralSettings(config) {
|
|
728
|
+
const answers = await inquirer.prompt([
|
|
729
|
+
{
|
|
730
|
+
type: "input",
|
|
731
|
+
name: "documentTitle",
|
|
732
|
+
message: "Document title:",
|
|
733
|
+
default: config.settings.documentTitle,
|
|
734
|
+
},
|
|
735
|
+
{
|
|
736
|
+
type: "number",
|
|
737
|
+
name: "maxFilesBeforePrompt",
|
|
738
|
+
message: "Max files before warning prompt:",
|
|
739
|
+
default: config.settings.maxFilesBeforePrompt,
|
|
740
|
+
validate: (input) => input > 0 || "Must be a positive number",
|
|
741
|
+
},
|
|
742
|
+
]);
|
|
743
|
+
|
|
744
|
+
config.settings.documentTitle = answers.documentTitle;
|
|
745
|
+
config.settings.maxFilesBeforePrompt = answers.maxFilesBeforePrompt;
|
|
746
|
+
|
|
747
|
+
return config;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Display current configuration in user-friendly format
|
|
752
|
+
* @param {object} config Configuration to display
|
|
753
|
+
*/
|
|
754
|
+
displayConfig(config) {
|
|
755
|
+
console.log(chalk.cyan("\nš Current Configuration\n"));
|
|
756
|
+
|
|
757
|
+
// Output Settings
|
|
758
|
+
console.log(chalk.green("š Output Settings:"));
|
|
759
|
+
if (config.output.mode === "fixed") {
|
|
760
|
+
console.log(chalk.gray(` ⢠Mode: Fixed folder`));
|
|
761
|
+
console.log(chalk.gray(` ⢠Location: ${config.output.fixedPath}`));
|
|
762
|
+
} else {
|
|
763
|
+
console.log(chalk.gray(` ⢠Mode: Current directory`));
|
|
764
|
+
}
|
|
765
|
+
console.log();
|
|
766
|
+
|
|
767
|
+
// File Types
|
|
768
|
+
console.log(chalk.green("š Included File Types:"));
|
|
769
|
+
const extensions = config.allowedExtensions || [];
|
|
770
|
+
if (extensions.length > 0) {
|
|
771
|
+
// Group by category for better readability
|
|
772
|
+
const webFiles = extensions.filter(ext => ['.html', '.css', '.scss', '.js', '.jsx', '.ts', '.tsx'].includes(ext));
|
|
773
|
+
const configFiles = extensions.filter(ext => ['.json', '.yaml', '.yml', '.xml'].includes(ext));
|
|
774
|
+
const docFiles = extensions.filter(ext => ['.md', '.txt'].includes(ext));
|
|
775
|
+
const codeFiles = extensions.filter(ext => ![...webFiles, ...configFiles, ...docFiles].includes(ext));
|
|
776
|
+
|
|
777
|
+
if (webFiles.length > 0) {
|
|
778
|
+
console.log(chalk.gray(` ⢠Web files: ${webFiles.join(', ')}`));
|
|
779
|
+
}
|
|
780
|
+
if (codeFiles.length > 0) {
|
|
781
|
+
console.log(chalk.gray(` ⢠Code files: ${codeFiles.join(', ')}`));
|
|
782
|
+
}
|
|
783
|
+
if (configFiles.length > 0) {
|
|
784
|
+
console.log(chalk.gray(` ⢠Config files: ${configFiles.join(', ')}`));
|
|
785
|
+
}
|
|
786
|
+
if (docFiles.length > 0) {
|
|
787
|
+
console.log(chalk.gray(` ⢠Documentation: ${docFiles.join(', ')}`));
|
|
788
|
+
}
|
|
789
|
+
} else {
|
|
790
|
+
console.log(chalk.gray(` ⢠No file types configured`));
|
|
791
|
+
}
|
|
792
|
+
console.log();
|
|
793
|
+
|
|
794
|
+
// Excluded Directories
|
|
795
|
+
console.log(chalk.green("š« Skipped Directories:"));
|
|
796
|
+
const excludeDirs = config.excludeDirs || [];
|
|
797
|
+
if (excludeDirs.length > 0) {
|
|
798
|
+
excludeDirs.forEach(dir => {
|
|
799
|
+
console.log(chalk.gray(` ⢠${dir}/`));
|
|
800
|
+
});
|
|
801
|
+
} else {
|
|
802
|
+
console.log(chalk.gray(` ⢠None`));
|
|
803
|
+
}
|
|
804
|
+
console.log();
|
|
805
|
+
|
|
806
|
+
// Excluded Files
|
|
807
|
+
console.log(chalk.green("š« Skipped File Patterns:"));
|
|
808
|
+
const excludeFiles = config.excludeFiles || [];
|
|
809
|
+
if (excludeFiles.length > 0) {
|
|
810
|
+
excludeFiles.forEach(pattern => {
|
|
811
|
+
console.log(chalk.gray(` ⢠${pattern}`));
|
|
812
|
+
});
|
|
813
|
+
} else {
|
|
814
|
+
console.log(chalk.gray(` ⢠None`));
|
|
815
|
+
}
|
|
816
|
+
console.log();
|
|
817
|
+
|
|
818
|
+
// General Settings
|
|
819
|
+
console.log(chalk.green("āļø General Settings:"));
|
|
820
|
+
console.log(chalk.gray(` ⢠Document title: "${config.settings?.documentTitle || 'Project Code Summary'}"`));
|
|
821
|
+
console.log(chalk.gray(` ⢠File warning threshold: ${config.settings?.maxFilesBeforePrompt || 500} files`));
|
|
822
|
+
console.log(chalk.gray(` ⢠Configuration version: ${config.configVersion || 'legacy'}`));
|
|
823
|
+
console.log();
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
export default ConfigManager;
|