@mytechtoday/augment-extensions 0.5.0 → 0.7.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/cli/dist/cli.js +4 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/show.d.ts +4 -0
- package/cli/dist/commands/show.d.ts.map +1 -1
- package/cli/dist/commands/show.js +456 -23
- package/cli/dist/commands/show.js.map +1 -1
- package/cli/dist/utils/config-system.d.ts +111 -0
- package/cli/dist/utils/config-system.d.ts.map +1 -0
- package/cli/dist/utils/config-system.js +239 -0
- package/cli/dist/utils/config-system.js.map +1 -0
- package/cli/dist/utils/hook-system.d.ts +84 -0
- package/cli/dist/utils/hook-system.d.ts.map +1 -0
- package/cli/dist/utils/hook-system.js +151 -0
- package/cli/dist/utils/hook-system.js.map +1 -0
- package/cli/dist/utils/inspection-cache.d.ts +56 -0
- package/cli/dist/utils/inspection-cache.d.ts.map +1 -0
- package/cli/dist/utils/inspection-cache.js +166 -0
- package/cli/dist/utils/inspection-cache.js.map +1 -0
- package/cli/dist/utils/inspection-handlers.d.ts +75 -0
- package/cli/dist/utils/inspection-handlers.d.ts.map +1 -0
- package/cli/dist/utils/inspection-handlers.js +171 -0
- package/cli/dist/utils/inspection-handlers.js.map +1 -0
- package/cli/dist/utils/module-system.d.ts +1 -0
- package/cli/dist/utils/module-system.d.ts.map +1 -1
- package/cli/dist/utils/module-system.js +8 -3
- package/cli/dist/utils/module-system.js.map +1 -1
- package/cli/dist/utils/plugin-system.d.ts +133 -0
- package/cli/dist/utils/plugin-system.d.ts.map +1 -0
- package/cli/dist/utils/plugin-system.js +210 -0
- package/cli/dist/utils/plugin-system.js.map +1 -0
- package/cli/dist/utils/progress.d.ts +67 -0
- package/cli/dist/utils/progress.d.ts.map +1 -0
- package/cli/dist/utils/progress.js +146 -0
- package/cli/dist/utils/progress.js.map +1 -0
- package/cli/dist/utils/stream-reader.d.ts +34 -0
- package/cli/dist/utils/stream-reader.d.ts.map +1 -0
- package/cli/dist/utils/stream-reader.js +147 -0
- package/cli/dist/utils/stream-reader.js.map +1 -0
- package/cli/dist/utils/vscode-editor.d.ts +45 -0
- package/cli/dist/utils/vscode-editor.d.ts.map +1 -0
- package/cli/dist/utils/vscode-editor.js +171 -0
- package/cli/dist/utils/vscode-editor.js.map +1 -0
- package/cli/dist/utils/vscode-links.d.ts +49 -0
- package/cli/dist/utils/vscode-links.d.ts.map +1 -0
- package/cli/dist/utils/vscode-links.js +167 -0
- package/cli/dist/utils/vscode-links.js.map +1 -0
- package/package.json +1 -1
|
@@ -41,7 +41,13 @@ exports.showModuleCommand = showModuleCommand;
|
|
|
41
41
|
const chalk_1 = __importDefault(require("chalk"));
|
|
42
42
|
const fs = __importStar(require("fs"));
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
|
+
const highlight_js_1 = __importDefault(require("highlight.js"));
|
|
44
45
|
const module_system_1 = require("../utils/module-system");
|
|
46
|
+
const inspection_cache_1 = require("../utils/inspection-cache");
|
|
47
|
+
const stream_reader_1 = require("../utils/stream-reader");
|
|
48
|
+
const progress_1 = require("../utils/progress");
|
|
49
|
+
const vscode_links_1 = require("../utils/vscode-links");
|
|
50
|
+
const vscode_editor_1 = require("../utils/vscode-editor");
|
|
45
51
|
/**
|
|
46
52
|
* Legacy show command - displays basic module information
|
|
47
53
|
* @deprecated Use showModuleCommand for enhanced inspection
|
|
@@ -116,6 +122,10 @@ async function showModuleCommand(moduleName, filePath, options) {
|
|
|
116
122
|
console.log(chalk_1.default.gray(' augx show module php-standards rules/psr-standards.md'));
|
|
117
123
|
process.exit(1);
|
|
118
124
|
}
|
|
125
|
+
// Disable cache if --no-cache flag is set
|
|
126
|
+
if (options.noCache) {
|
|
127
|
+
inspection_cache_1.moduleInspectionCache.setEnabled(false);
|
|
128
|
+
}
|
|
119
129
|
// Discover and validate module using enhanced discovery
|
|
120
130
|
const module = (0, module_system_1.findModuleEnhanced)(moduleName);
|
|
121
131
|
if (!module) {
|
|
@@ -144,12 +154,20 @@ async function showModuleCommand(moduleName, filePath, options) {
|
|
|
144
154
|
// Module overview (default)
|
|
145
155
|
await showModuleOverview(module, options);
|
|
146
156
|
}
|
|
157
|
+
// Re-enable cache after command completes
|
|
158
|
+
if (options.noCache) {
|
|
159
|
+
inspection_cache_1.moduleInspectionCache.setEnabled(true);
|
|
160
|
+
}
|
|
147
161
|
}
|
|
148
162
|
catch (error) {
|
|
149
163
|
console.error(chalk_1.default.red('Error inspecting module:'), error);
|
|
150
164
|
if (error instanceof Error) {
|
|
151
165
|
console.error(chalk_1.default.gray(error.message));
|
|
152
166
|
}
|
|
167
|
+
// Re-enable cache on error
|
|
168
|
+
if (options.noCache) {
|
|
169
|
+
inspection_cache_1.moduleInspectionCache.setEnabled(true);
|
|
170
|
+
}
|
|
153
171
|
process.exit(1);
|
|
154
172
|
}
|
|
155
173
|
}
|
|
@@ -157,11 +175,18 @@ async function showModuleCommand(moduleName, filePath, options) {
|
|
|
157
175
|
* Display module overview with metadata and file listing
|
|
158
176
|
*/
|
|
159
177
|
async function showModuleOverview(module, options) {
|
|
160
|
-
//
|
|
161
|
-
const
|
|
178
|
+
// Try to get from cache first
|
|
179
|
+
const cacheKey = `overview:${module.fullName}`;
|
|
180
|
+
let extendedMetadata = inspection_cache_1.moduleInspectionCache.get(cacheKey, module.path);
|
|
162
181
|
if (!extendedMetadata) {
|
|
163
|
-
|
|
164
|
-
|
|
182
|
+
// Extract comprehensive metadata
|
|
183
|
+
extendedMetadata = (0, module_system_1.extractModuleMetadata)(module.path);
|
|
184
|
+
if (!extendedMetadata) {
|
|
185
|
+
console.error(chalk_1.default.red('Failed to extract module metadata'));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// Cache the result
|
|
189
|
+
inspection_cache_1.moduleInspectionCache.set(cacheKey, extendedMetadata, module.path);
|
|
165
190
|
}
|
|
166
191
|
// Handle JSON output format
|
|
167
192
|
if (options.json || options.format === 'json') {
|
|
@@ -189,7 +214,69 @@ async function showModuleOverview(module, options) {
|
|
|
189
214
|
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
190
215
|
return;
|
|
191
216
|
}
|
|
192
|
-
//
|
|
217
|
+
// Handle Markdown output format
|
|
218
|
+
if (options.format === 'markdown') {
|
|
219
|
+
console.log(`# ${module.fullName}\n`);
|
|
220
|
+
console.log(`**Version:** ${extendedMetadata.version}\n`);
|
|
221
|
+
console.log(`**Type:** ${extendedMetadata.type}\n`);
|
|
222
|
+
console.log(`**Description:** ${extendedMetadata.description}\n`);
|
|
223
|
+
if (extendedMetadata.tags && extendedMetadata.tags.length > 0) {
|
|
224
|
+
console.log(`**Tags:** ${extendedMetadata.tags.join(', ')}\n`);
|
|
225
|
+
}
|
|
226
|
+
console.log(`## Files\n`);
|
|
227
|
+
console.log(`- Total: ${extendedMetadata.files?.total || 0}`);
|
|
228
|
+
console.log(`- Rules: ${extendedMetadata.files?.rules || 0}`);
|
|
229
|
+
console.log(`- Examples: ${extendedMetadata.files?.examples || 0}`);
|
|
230
|
+
console.log(`- Other: ${extendedMetadata.files?.other || 0}\n`);
|
|
231
|
+
console.log(`## Size\n`);
|
|
232
|
+
const totalBytes = extendedMetadata.size?.totalBytes || 0;
|
|
233
|
+
const totalChars = extendedMetadata.size?.totalCharacters || 0;
|
|
234
|
+
console.log(`- Total: ${formatBytes(totalBytes)} (${totalBytes.toLocaleString()} bytes)`);
|
|
235
|
+
console.log(`- Characters: ${totalChars.toLocaleString()}\n`);
|
|
236
|
+
if (extendedMetadata.lastModified) {
|
|
237
|
+
console.log(`**Last Modified:** ${formatDate(extendedMetadata.lastModified)}\n`);
|
|
238
|
+
}
|
|
239
|
+
console.log(`**Location:** \`${module.path}\`\n`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
// Handle plain text output format (ASCII-only, no colors)
|
|
243
|
+
if (options.format === 'text') {
|
|
244
|
+
console.log();
|
|
245
|
+
console.log(`Module: ${module.fullName}`);
|
|
246
|
+
console.log('='.repeat(60));
|
|
247
|
+
console.log();
|
|
248
|
+
console.log('Metadata:');
|
|
249
|
+
console.log(` Name: ${extendedMetadata.displayName}`);
|
|
250
|
+
console.log(` Version: ${extendedMetadata.version}`);
|
|
251
|
+
console.log(` Type: ${extendedMetadata.type}`);
|
|
252
|
+
console.log(` Description: ${extendedMetadata.description}`);
|
|
253
|
+
if (extendedMetadata.tags && extendedMetadata.tags.length > 0) {
|
|
254
|
+
console.log(` Tags: ${extendedMetadata.tags.join(', ')}`);
|
|
255
|
+
}
|
|
256
|
+
console.log();
|
|
257
|
+
console.log('Files:');
|
|
258
|
+
console.log(` Total: ${extendedMetadata.files?.total || 0}`);
|
|
259
|
+
console.log(` Rules: ${extendedMetadata.files?.rules || 0}`);
|
|
260
|
+
console.log(` Examples: ${extendedMetadata.files?.examples || 0}`);
|
|
261
|
+
console.log(` Other: ${extendedMetadata.files?.other || 0}`);
|
|
262
|
+
console.log();
|
|
263
|
+
console.log('Size:');
|
|
264
|
+
const totalBytes = extendedMetadata.size?.totalBytes || 0;
|
|
265
|
+
const totalChars = extendedMetadata.size?.totalCharacters || 0;
|
|
266
|
+
console.log(` Total: ${formatBytes(totalBytes)} (${totalBytes.toLocaleString()} bytes)`);
|
|
267
|
+
console.log(` Characters: ${totalChars.toLocaleString()}`);
|
|
268
|
+
console.log();
|
|
269
|
+
if (extendedMetadata.lastModified) {
|
|
270
|
+
console.log('Last Modified:');
|
|
271
|
+
console.log(` ${formatDate(extendedMetadata.lastModified)}`);
|
|
272
|
+
console.log();
|
|
273
|
+
}
|
|
274
|
+
console.log('Location:');
|
|
275
|
+
console.log(` ${module.path}`);
|
|
276
|
+
console.log();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
// Colored text output format (default)
|
|
193
280
|
console.log();
|
|
194
281
|
console.log(chalk_1.default.bold.blue(`📦 ${module.fullName}`));
|
|
195
282
|
console.log(chalk_1.default.gray('─'.repeat(60)));
|
|
@@ -289,7 +376,8 @@ async function showModuleContent(module, options) {
|
|
|
289
376
|
const files = listModuleFiles(module.path, {
|
|
290
377
|
recursive: true,
|
|
291
378
|
filter: options.filter || '*.md',
|
|
292
|
-
groupByDirectory: true
|
|
379
|
+
groupByDirectory: true,
|
|
380
|
+
depth: options.depth
|
|
293
381
|
});
|
|
294
382
|
if (files.length === 0) {
|
|
295
383
|
console.log(chalk_1.default.yellow('No markdown files found in module'));
|
|
@@ -320,12 +408,22 @@ async function showModuleContent(module, options) {
|
|
|
320
408
|
modified: f.modified,
|
|
321
409
|
type: f.type
|
|
322
410
|
})),
|
|
323
|
-
content: files.map(f =>
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
411
|
+
content: files.map(f => {
|
|
412
|
+
let content = fs.readFileSync(f.path, 'utf-8');
|
|
413
|
+
if (options.secure) {
|
|
414
|
+
content = redactSensitiveData(content, false);
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
file: f.relativePath,
|
|
418
|
+
content: content
|
|
419
|
+
};
|
|
420
|
+
})
|
|
327
421
|
};
|
|
328
422
|
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
423
|
+
// Log redactions summary if secure mode is enabled
|
|
424
|
+
if (options.secure) {
|
|
425
|
+
console.error(chalk_1.default.yellow('\n⚠️ Sensitive data has been redacted from output'));
|
|
426
|
+
}
|
|
329
427
|
return;
|
|
330
428
|
}
|
|
331
429
|
// Handle Markdown output format
|
|
@@ -333,16 +431,61 @@ async function showModuleContent(module, options) {
|
|
|
333
431
|
console.log(`# ${module.fullName}\n`);
|
|
334
432
|
console.log(`**Module Type:** ${module.metadata.type}\n`);
|
|
335
433
|
console.log(`**Version:** ${module.metadata.version}\n`);
|
|
434
|
+
if (options.secure) {
|
|
435
|
+
console.log(`**Security:** Sensitive data redacted\n`);
|
|
436
|
+
}
|
|
336
437
|
console.log(`---\n`);
|
|
337
438
|
for (const file of files) {
|
|
338
439
|
console.log(`## ${file.relativePath}\n`);
|
|
339
|
-
|
|
440
|
+
let content = fs.readFileSync(file.path, 'utf-8');
|
|
441
|
+
if (options.secure) {
|
|
442
|
+
content = redactSensitiveData(content, false);
|
|
443
|
+
}
|
|
340
444
|
console.log(content);
|
|
341
445
|
console.log('\n---\n');
|
|
342
446
|
}
|
|
447
|
+
if (options.secure) {
|
|
448
|
+
console.log(`\n> ⚠️ Sensitive data has been redacted from this output\n`);
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
// Handle plain text output format (ASCII-only, no colors)
|
|
453
|
+
if (options.format === 'text') {
|
|
454
|
+
console.log();
|
|
455
|
+
console.log(`Aggregated Content: ${module.fullName}`);
|
|
456
|
+
console.log('='.repeat(60));
|
|
457
|
+
console.log();
|
|
458
|
+
console.log(`Files: ${files.length}`);
|
|
459
|
+
if (options.secure) {
|
|
460
|
+
console.log('Security: Sensitive data redacted');
|
|
461
|
+
}
|
|
462
|
+
console.log();
|
|
463
|
+
for (const file of files) {
|
|
464
|
+
console.log(`File: ${file.relativePath}`);
|
|
465
|
+
console.log(`Size: ${formatBytes(file.size)} | Modified: ${formatDate(file.modified)}`);
|
|
466
|
+
console.log('-'.repeat(60));
|
|
467
|
+
console.log();
|
|
468
|
+
let content = fs.readFileSync(file.path, 'utf-8');
|
|
469
|
+
if (options.secure) {
|
|
470
|
+
content = redactSensitiveData(content, false);
|
|
471
|
+
}
|
|
472
|
+
console.log(content);
|
|
473
|
+
console.log();
|
|
474
|
+
console.log('='.repeat(60));
|
|
475
|
+
console.log();
|
|
476
|
+
}
|
|
477
|
+
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
478
|
+
console.log('Summary:');
|
|
479
|
+
console.log(` Total files: ${files.length}`);
|
|
480
|
+
console.log(` Total size: ${formatBytes(totalSize)}`);
|
|
481
|
+
if (options.secure) {
|
|
482
|
+
console.log();
|
|
483
|
+
console.log('WARNING: Sensitive data has been redacted from this output');
|
|
484
|
+
}
|
|
485
|
+
console.log();
|
|
343
486
|
return;
|
|
344
487
|
}
|
|
345
|
-
//
|
|
488
|
+
// Colored text output format (default)
|
|
346
489
|
console.log();
|
|
347
490
|
console.log(chalk_1.default.bold.blue(`📄 Aggregated Content: ${module.fullName}`));
|
|
348
491
|
console.log(chalk_1.default.gray('─'.repeat(60)));
|
|
@@ -360,6 +503,9 @@ async function showModuleContent(module, options) {
|
|
|
360
503
|
paginationInfo = ` (Page ${currentPage} of ${totalPages})`;
|
|
361
504
|
}
|
|
362
505
|
console.log(chalk_1.default.bold(`Files: ${files.length}${paginationInfo}`));
|
|
506
|
+
if (options.secure) {
|
|
507
|
+
console.log(chalk_1.default.yellow('🔒 Security: Sensitive data redacted'));
|
|
508
|
+
}
|
|
363
509
|
console.log();
|
|
364
510
|
// Display each file with section headers
|
|
365
511
|
for (const file of filesToDisplay) {
|
|
@@ -367,7 +513,10 @@ async function showModuleContent(module, options) {
|
|
|
367
513
|
console.log(chalk_1.default.gray(`│ Size: ${formatBytes(file.size)} | Modified: ${formatDate(file.modified)}`));
|
|
368
514
|
console.log(chalk_1.default.bold.cyan('└' + '─'.repeat(58)));
|
|
369
515
|
console.log();
|
|
370
|
-
|
|
516
|
+
let content = fs.readFileSync(file.path, 'utf-8');
|
|
517
|
+
if (options.secure) {
|
|
518
|
+
content = redactSensitiveData(content, false);
|
|
519
|
+
}
|
|
371
520
|
// Preserve markdown formatting
|
|
372
521
|
console.log(content);
|
|
373
522
|
console.log();
|
|
@@ -391,6 +540,10 @@ async function showModuleContent(module, options) {
|
|
|
391
540
|
console.log(chalk_1.default.cyan(` Prev page: augx show module ${module.fullName} --content --page ${currentPage - 1}`));
|
|
392
541
|
}
|
|
393
542
|
}
|
|
543
|
+
if (options.secure) {
|
|
544
|
+
console.log();
|
|
545
|
+
console.log(chalk_1.default.yellow('⚠️ Sensitive data has been redacted from this output'));
|
|
546
|
+
}
|
|
394
547
|
console.log();
|
|
395
548
|
}
|
|
396
549
|
/**
|
|
@@ -413,10 +566,71 @@ async function showModuleFile(module, filePath, options) {
|
|
|
413
566
|
console.log(chalk_1.default.gray(`Module path: ${module.path}`));
|
|
414
567
|
process.exit(1);
|
|
415
568
|
}
|
|
416
|
-
//
|
|
417
|
-
|
|
418
|
-
|
|
569
|
+
// Handle --open flag: Open file in VS Code editor
|
|
570
|
+
if (options.open) {
|
|
571
|
+
try {
|
|
572
|
+
if (!(0, vscode_editor_1.isVSCodeAvailable)()) {
|
|
573
|
+
console.error(chalk_1.default.red('VS Code CLI is not available. Please install VS Code and ensure "code" is in your PATH.'));
|
|
574
|
+
process.exit(1);
|
|
575
|
+
}
|
|
576
|
+
await (0, vscode_editor_1.openInEditor)(fullPath);
|
|
577
|
+
console.log(chalk_1.default.green(`✓ Opened ${path.basename(fullPath)} in VS Code editor`));
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
catch (error) {
|
|
581
|
+
console.error(chalk_1.default.red(`Failed to open file: ${error instanceof Error ? error.message : String(error)}`));
|
|
582
|
+
process.exit(1);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
// Handle --preview flag: Open file in VS Code preview pane
|
|
586
|
+
if (options.preview) {
|
|
587
|
+
try {
|
|
588
|
+
if (!(0, vscode_editor_1.isVSCodeAvailable)()) {
|
|
589
|
+
console.error(chalk_1.default.red('VS Code CLI is not available. Please install VS Code and ensure "code" is in your PATH.'));
|
|
590
|
+
process.exit(1);
|
|
591
|
+
}
|
|
592
|
+
await (0, vscode_editor_1.openInPreview)(fullPath);
|
|
593
|
+
console.log(chalk_1.default.green(`✓ Opened ${path.basename(fullPath)} in VS Code preview pane`));
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
catch (error) {
|
|
597
|
+
console.error(chalk_1.default.red(`Failed to open file: ${error instanceof Error ? error.message : String(error)}`));
|
|
598
|
+
process.exit(1);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
419
601
|
const stats = fs.statSync(fullPath);
|
|
602
|
+
const fileSizeThreshold = 1024 * 1024; // 1MB threshold for streaming
|
|
603
|
+
// Use streaming for large files
|
|
604
|
+
let content;
|
|
605
|
+
if (stats.size > fileSizeThreshold) {
|
|
606
|
+
// Show progress for large files
|
|
607
|
+
const spinner = new progress_1.Spinner(`Reading large file (${formatBytes(stats.size)})...`);
|
|
608
|
+
spinner.start();
|
|
609
|
+
try {
|
|
610
|
+
// Stream large files
|
|
611
|
+
const chunks = [];
|
|
612
|
+
await (0, stream_reader_1.readFileStreaming)(fullPath, async (chunk, streamStats) => {
|
|
613
|
+
chunks.push(chunk);
|
|
614
|
+
const progress = (streamStats.bytesRead / stats.size) * 100;
|
|
615
|
+
spinner.setText(`Reading large file: ${progress.toFixed(1)}% (${formatBytes(streamStats.bytesRead)}/${formatBytes(stats.size)})`);
|
|
616
|
+
}, { highWaterMark: 64 * 1024 });
|
|
617
|
+
content = chunks.join('');
|
|
618
|
+
spinner.stop(chalk_1.default.green('✓ File loaded successfully'));
|
|
619
|
+
}
|
|
620
|
+
catch (error) {
|
|
621
|
+
spinner.stop(chalk_1.default.red('✗ Failed to read file'));
|
|
622
|
+
throw error;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
// Read small files normally
|
|
627
|
+
content = fs.readFileSync(fullPath, 'utf-8');
|
|
628
|
+
}
|
|
629
|
+
// Apply redaction if secure flag is set
|
|
630
|
+
if (options.secure) {
|
|
631
|
+
content = redactSensitiveData(content, true);
|
|
632
|
+
}
|
|
633
|
+
const lines = content.split('\n');
|
|
420
634
|
// Get relative path for display
|
|
421
635
|
const relativePath = path.relative(module.path, fullPath);
|
|
422
636
|
// Handle JSON output format
|
|
@@ -443,27 +657,87 @@ async function showModuleFile(module, filePath, options) {
|
|
|
443
657
|
console.log('```');
|
|
444
658
|
return;
|
|
445
659
|
}
|
|
446
|
-
//
|
|
660
|
+
// Handle plain text output format (ASCII-only, no colors, no line numbers)
|
|
661
|
+
if (options.format === 'text') {
|
|
662
|
+
console.log();
|
|
663
|
+
console.log(`File: ${relativePath}`);
|
|
664
|
+
console.log('='.repeat(60));
|
|
665
|
+
console.log();
|
|
666
|
+
console.log('File Information:');
|
|
667
|
+
console.log(` Module: ${module.fullName}`);
|
|
668
|
+
console.log(` Path: ${relativePath}`);
|
|
669
|
+
console.log(` Size: ${formatBytes(stats.size)}`);
|
|
670
|
+
console.log(` Lines: ${lines.length}`);
|
|
671
|
+
console.log(` Modified: ${formatDate(stats.mtime)}`);
|
|
672
|
+
const detectedLang = detectLanguage(fullPath);
|
|
673
|
+
if (detectedLang) {
|
|
674
|
+
console.log(` Language: ${detectedLang}`);
|
|
675
|
+
}
|
|
676
|
+
console.log();
|
|
677
|
+
console.log('Content:');
|
|
678
|
+
console.log('-'.repeat(60));
|
|
679
|
+
console.log();
|
|
680
|
+
console.log(content);
|
|
681
|
+
console.log();
|
|
682
|
+
console.log('='.repeat(60));
|
|
683
|
+
console.log();
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
// Colored text output format (default) with line numbers
|
|
687
|
+
const workspaceRoot = (0, vscode_links_1.getWorkspaceRoot)();
|
|
688
|
+
const clickablePath = (0, vscode_links_1.formatClickablePath)(fullPath, { workspaceRoot });
|
|
447
689
|
console.log();
|
|
448
690
|
console.log(chalk_1.default.bold.blue(`📄 ${relativePath}`));
|
|
691
|
+
console.log(chalk_1.default.gray(` ${clickablePath}`));
|
|
449
692
|
console.log(chalk_1.default.gray('─'.repeat(60)));
|
|
450
693
|
console.log();
|
|
451
694
|
console.log(chalk_1.default.bold('File Information:'));
|
|
452
695
|
console.log(chalk_1.default.gray(` Module: ${module.fullName}`));
|
|
453
696
|
console.log(chalk_1.default.gray(` Path: ${relativePath}`));
|
|
697
|
+
console.log(chalk_1.default.gray(` Full: ${clickablePath}`));
|
|
454
698
|
console.log(chalk_1.default.gray(` Size: ${formatBytes(stats.size)}`));
|
|
455
699
|
console.log(chalk_1.default.gray(` Lines: ${lines.length}`));
|
|
456
700
|
console.log(chalk_1.default.gray(` Modified: ${formatDate(stats.mtime)}`));
|
|
701
|
+
// Display detected language
|
|
702
|
+
const detectedLang = detectLanguage(fullPath);
|
|
703
|
+
if (detectedLang) {
|
|
704
|
+
console.log(chalk_1.default.gray(` Language: ${detectedLang}`));
|
|
705
|
+
}
|
|
457
706
|
console.log();
|
|
458
707
|
console.log(chalk_1.default.bold('Content:'));
|
|
459
708
|
console.log(chalk_1.default.gray('─'.repeat(60)));
|
|
460
709
|
console.log();
|
|
461
|
-
//
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
710
|
+
// Apply syntax highlighting if enabled (default: enabled)
|
|
711
|
+
const enableHighlighting = options.format !== 'text' && process.stdout.isTTY;
|
|
712
|
+
if (enableHighlighting && detectedLang) {
|
|
713
|
+
// Try to apply syntax highlighting
|
|
714
|
+
try {
|
|
715
|
+
const highlighted = applySyntaxHighlighting(content, fullPath, true);
|
|
716
|
+
const highlightedLines = highlighted.split('\n');
|
|
717
|
+
// Display with line numbers
|
|
718
|
+
const lineNumberWidth = highlightedLines.length.toString().length;
|
|
719
|
+
highlightedLines.forEach((line, index) => {
|
|
720
|
+
const lineNumber = (index + 1).toString().padStart(lineNumberWidth, ' ');
|
|
721
|
+
console.log(chalk_1.default.gray(`${lineNumber} │ `) + line);
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
// Fallback to plain display if highlighting fails
|
|
726
|
+
const lineNumberWidth = lines.length.toString().length;
|
|
727
|
+
lines.forEach((line, index) => {
|
|
728
|
+
const lineNumber = (index + 1).toString().padStart(lineNumberWidth, ' ');
|
|
729
|
+
console.log(chalk_1.default.gray(`${lineNumber} │ `) + line);
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
else {
|
|
734
|
+
// Display content with line numbers (no highlighting)
|
|
735
|
+
const lineNumberWidth = lines.length.toString().length;
|
|
736
|
+
lines.forEach((line, index) => {
|
|
737
|
+
const lineNumber = (index + 1).toString().padStart(lineNumberWidth, ' ');
|
|
738
|
+
console.log(chalk_1.default.gray(`${lineNumber} │ `) + line);
|
|
739
|
+
});
|
|
740
|
+
}
|
|
467
741
|
console.log();
|
|
468
742
|
console.log(chalk_1.default.gray('─'.repeat(60)));
|
|
469
743
|
console.log();
|
|
@@ -551,6 +825,100 @@ function highlightSearchTerm(text, searchTerm) {
|
|
|
551
825
|
const regex = new RegExp(`(${searchTerm})`, 'gi');
|
|
552
826
|
return text.replace(regex, chalk_1.default.yellow.bold('$1'));
|
|
553
827
|
}
|
|
828
|
+
/**
|
|
829
|
+
* Apply syntax highlighting to code content
|
|
830
|
+
* Detects language from file extension and applies appropriate highlighting
|
|
831
|
+
*/
|
|
832
|
+
function applySyntaxHighlighting(content, filePath, enableColors = true) {
|
|
833
|
+
if (!enableColors) {
|
|
834
|
+
return content;
|
|
835
|
+
}
|
|
836
|
+
try {
|
|
837
|
+
// Detect language from file extension
|
|
838
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
839
|
+
const languageMap = {
|
|
840
|
+
'.ts': 'typescript',
|
|
841
|
+
'.js': 'javascript',
|
|
842
|
+
'.jsx': 'javascript',
|
|
843
|
+
'.tsx': 'typescript',
|
|
844
|
+
'.py': 'python',
|
|
845
|
+
'.php': 'php',
|
|
846
|
+
'.rb': 'ruby',
|
|
847
|
+
'.go': 'go',
|
|
848
|
+
'.rs': 'rust',
|
|
849
|
+
'.java': 'java',
|
|
850
|
+
'.c': 'c',
|
|
851
|
+
'.cpp': 'cpp',
|
|
852
|
+
'.cs': 'csharp',
|
|
853
|
+
'.sh': 'bash',
|
|
854
|
+
'.ps1': 'powershell',
|
|
855
|
+
'.md': 'markdown',
|
|
856
|
+
'.json': 'json',
|
|
857
|
+
'.yaml': 'yaml',
|
|
858
|
+
'.yml': 'yaml',
|
|
859
|
+
'.xml': 'xml',
|
|
860
|
+
'.html': 'html',
|
|
861
|
+
'.css': 'css',
|
|
862
|
+
'.scss': 'scss',
|
|
863
|
+
'.sql': 'sql'
|
|
864
|
+
};
|
|
865
|
+
const language = languageMap[ext];
|
|
866
|
+
if (language) {
|
|
867
|
+
const highlighted = highlight_js_1.default.highlight(content, { language, ignoreIllegals: true });
|
|
868
|
+
return highlighted.value;
|
|
869
|
+
}
|
|
870
|
+
// Auto-detect if no extension match
|
|
871
|
+
const autoDetected = highlight_js_1.default.highlightAuto(content);
|
|
872
|
+
return autoDetected.value;
|
|
873
|
+
}
|
|
874
|
+
catch (error) {
|
|
875
|
+
// If highlighting fails, return original content
|
|
876
|
+
return content;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Convert ANSI color codes from highlight.js to chalk colors
|
|
881
|
+
* This is a simplified version - highlight.js uses HTML-like tags
|
|
882
|
+
*/
|
|
883
|
+
function convertHighlightToChalk(highlightedCode) {
|
|
884
|
+
// highlight.js returns HTML-like output, we need to convert to terminal colors
|
|
885
|
+
// For now, return as-is since we're using it in terminal context
|
|
886
|
+
// A more sophisticated implementation would parse the HTML and apply chalk colors
|
|
887
|
+
return highlightedCode;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Detect language from file extension
|
|
891
|
+
*/
|
|
892
|
+
function detectLanguage(filePath) {
|
|
893
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
894
|
+
const languageMap = {
|
|
895
|
+
'.ts': 'TypeScript',
|
|
896
|
+
'.js': 'JavaScript',
|
|
897
|
+
'.jsx': 'JavaScript (JSX)',
|
|
898
|
+
'.tsx': 'TypeScript (TSX)',
|
|
899
|
+
'.py': 'Python',
|
|
900
|
+
'.php': 'PHP',
|
|
901
|
+
'.rb': 'Ruby',
|
|
902
|
+
'.go': 'Go',
|
|
903
|
+
'.rs': 'Rust',
|
|
904
|
+
'.java': 'Java',
|
|
905
|
+
'.c': 'C',
|
|
906
|
+
'.cpp': 'C++',
|
|
907
|
+
'.cs': 'C#',
|
|
908
|
+
'.sh': 'Bash',
|
|
909
|
+
'.ps1': 'PowerShell',
|
|
910
|
+
'.md': 'Markdown',
|
|
911
|
+
'.json': 'JSON',
|
|
912
|
+
'.yaml': 'YAML',
|
|
913
|
+
'.yml': 'YAML',
|
|
914
|
+
'.xml': 'XML',
|
|
915
|
+
'.html': 'HTML',
|
|
916
|
+
'.css': 'CSS',
|
|
917
|
+
'.scss': 'SCSS',
|
|
918
|
+
'.sql': 'SQL'
|
|
919
|
+
};
|
|
920
|
+
return languageMap[ext] || null;
|
|
921
|
+
}
|
|
554
922
|
/**
|
|
555
923
|
* Get similar modules for legacy showCommand
|
|
556
924
|
* @deprecated Use getModuleSuggestions from module-system instead
|
|
@@ -559,4 +927,69 @@ async function getSimilarModules(searchTerm) {
|
|
|
559
927
|
const suggestions = (0, module_system_1.getModuleSuggestions)(searchTerm, 5);
|
|
560
928
|
return suggestions.map(m => m.fullName);
|
|
561
929
|
}
|
|
930
|
+
/**
|
|
931
|
+
* Redaction patterns for sensitive data
|
|
932
|
+
*/
|
|
933
|
+
const REDACTION_PATTERNS = [
|
|
934
|
+
// API Keys
|
|
935
|
+
{ pattern: /\b([A-Za-z0-9_-]*API[_-]?KEY[_-]?[A-Za-z0-9_-]*)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'API_KEY' },
|
|
936
|
+
{ pattern: /\b(api[_-]?key)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'API_KEY' },
|
|
937
|
+
// Secrets
|
|
938
|
+
{ pattern: /\b([A-Za-z0-9_-]*SECRET[_-]?[A-Za-z0-9_-]*)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'SECRET' },
|
|
939
|
+
{ pattern: /\b(secret)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'SECRET' },
|
|
940
|
+
// Tokens
|
|
941
|
+
{ pattern: /\b([A-Za-z0-9_-]*TOKEN[_-]?[A-Za-z0-9_-]*)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'TOKEN' },
|
|
942
|
+
{ pattern: /\b(token)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'TOKEN' },
|
|
943
|
+
{ pattern: /\b(bearer)\s+([A-Za-z0-9_\-\/+=]{16,})/gi, name: 'BEARER_TOKEN' },
|
|
944
|
+
// Passwords
|
|
945
|
+
{ pattern: /\b([A-Za-z0-9_-]*PASSWORD[_-]?[A-Za-z0-9_-]*)\s*[:=]\s*['"]?([^\s'"]{8,})['"]?/gi, name: 'PASSWORD' },
|
|
946
|
+
{ pattern: /\b(password|passwd|pwd)\s*[:=]\s*['"]?([^\s'"]{8,})['"]?/gi, name: 'PASSWORD' },
|
|
947
|
+
// Private Keys
|
|
948
|
+
{ pattern: /(-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(?:RSA\s+)?PRIVATE\s+KEY-----)/gi, name: 'PRIVATE_KEY' },
|
|
949
|
+
// AWS Keys
|
|
950
|
+
{ pattern: /\b(AKIA[0-9A-Z]{16})\b/g, name: 'AWS_ACCESS_KEY' },
|
|
951
|
+
{ pattern: /\b([A-Za-z0-9/+=]{40})\b/g, name: 'AWS_SECRET_KEY' },
|
|
952
|
+
// GitHub Tokens
|
|
953
|
+
{ pattern: /\b(ghp_[A-Za-z0-9]{36})\b/g, name: 'GITHUB_TOKEN' },
|
|
954
|
+
{ pattern: /\b(gho_[A-Za-z0-9]{36})\b/g, name: 'GITHUB_OAUTH' },
|
|
955
|
+
{ pattern: /\b(ghu_[A-Za-z0-9]{36})\b/g, name: 'GITHUB_USER_TOKEN' },
|
|
956
|
+
{ pattern: /\b(ghs_[A-Za-z0-9]{36})\b/g, name: 'GITHUB_SERVER_TOKEN' },
|
|
957
|
+
{ pattern: /\b(ghr_[A-Za-z0-9]{36})\b/g, name: 'GITHUB_REFRESH_TOKEN' },
|
|
958
|
+
// Generic credentials
|
|
959
|
+
{ pattern: /\b(credentials?)\s*[:=]\s*['"]?([^\s'"]{16,})['"]?/gi, name: 'CREDENTIALS' },
|
|
960
|
+
{ pattern: /\b(auth)\s*[:=]\s*['"]?([A-Za-z0-9_\-\/+=]{16,})['"]?/gi, name: 'AUTH' }
|
|
961
|
+
];
|
|
962
|
+
/**
|
|
963
|
+
* Redact sensitive data from content
|
|
964
|
+
*/
|
|
965
|
+
function redactSensitiveData(content, logRedactions = false) {
|
|
966
|
+
let redactedContent = content;
|
|
967
|
+
const redactions = [];
|
|
968
|
+
for (const { pattern, name } of REDACTION_PATTERNS) {
|
|
969
|
+
const matches = content.match(pattern);
|
|
970
|
+
if (matches && matches.length > 0) {
|
|
971
|
+
redactedContent = redactedContent.replace(pattern, (match, ...args) => {
|
|
972
|
+
// For patterns with capture groups, preserve the key name but redact the value
|
|
973
|
+
if (args.length >= 2) {
|
|
974
|
+
const keyName = args[0];
|
|
975
|
+
return `${keyName}=[REDACTED_${name}]`;
|
|
976
|
+
}
|
|
977
|
+
// For patterns without capture groups, redact the entire match
|
|
978
|
+
return `[REDACTED_${name}]`;
|
|
979
|
+
});
|
|
980
|
+
if (logRedactions) {
|
|
981
|
+
redactions.push({ pattern: name, count: matches.length });
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
// Log redactions if requested
|
|
986
|
+
if (logRedactions && redactions.length > 0) {
|
|
987
|
+
console.log(chalk_1.default.yellow('\n⚠️ Sensitive data redacted:'));
|
|
988
|
+
for (const { pattern, count } of redactions) {
|
|
989
|
+
console.log(chalk_1.default.gray(` ${pattern}: ${count} occurrence(s)`));
|
|
990
|
+
}
|
|
991
|
+
console.log();
|
|
992
|
+
}
|
|
993
|
+
return redactedContent;
|
|
994
|
+
}
|
|
562
995
|
//# sourceMappingURL=show.js.map
|