vg-coder-cli 2.0.8 → 2.0.10

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 (75) hide show
  1. package/README.md +19 -0
  2. package/SYSTEM_PROMPT.md +157 -0
  3. package/coverage/base.css +224 -0
  4. package/coverage/block-navigation.js +87 -0
  5. package/coverage/favicon.png +0 -0
  6. package/coverage/index.html +206 -0
  7. package/coverage/lcov-report/base.css +224 -0
  8. package/coverage/lcov-report/block-navigation.js +87 -0
  9. package/coverage/lcov-report/favicon.png +0 -0
  10. package/coverage/lcov-report/index.html +206 -0
  11. package/coverage/lcov-report/prettify.css +1 -0
  12. package/coverage/lcov-report/prettify.js +2 -0
  13. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  14. package/coverage/lcov-report/sorter.js +210 -0
  15. package/coverage/lcov-report/src/detectors/index.html +116 -0
  16. package/coverage/lcov-report/src/detectors/project-detector.js.html +1084 -0
  17. package/coverage/lcov-report/src/exporter/html-exporter.js.html +2839 -0
  18. package/coverage/lcov-report/src/exporter/index.html +116 -0
  19. package/coverage/lcov-report/src/ignore/ignore-manager.js.html +979 -0
  20. package/coverage/lcov-report/src/ignore/index.html +116 -0
  21. package/coverage/lcov-report/src/index.html +116 -0
  22. package/coverage/lcov-report/src/index.js.html +928 -0
  23. package/coverage/lcov-report/src/scanner/file-scanner.js.html +1903 -0
  24. package/coverage/lcov-report/src/scanner/index.html +116 -0
  25. package/coverage/lcov-report/src/tokenizer/index.html +116 -0
  26. package/coverage/lcov-report/src/tokenizer/token-manager.js.html +1252 -0
  27. package/coverage/lcov-report/src/utils/helpers.js.html +469 -0
  28. package/coverage/lcov-report/src/utils/index.html +116 -0
  29. package/coverage/lcov.info +1396 -0
  30. package/coverage/prettify.css +1 -0
  31. package/coverage/prettify.js +2 -0
  32. package/coverage/sort-arrow-sprite.png +0 -0
  33. package/coverage/sorter.js +210 -0
  34. package/coverage/src/detectors/index.html +116 -0
  35. package/coverage/src/detectors/project-detector.js.html +1084 -0
  36. package/coverage/src/exporter/html-exporter.js.html +2839 -0
  37. package/coverage/src/exporter/index.html +116 -0
  38. package/coverage/src/ignore/ignore-manager.js.html +979 -0
  39. package/coverage/src/ignore/index.html +116 -0
  40. package/coverage/src/index.html +116 -0
  41. package/coverage/src/index.js.html +928 -0
  42. package/coverage/src/scanner/file-scanner.js.html +1903 -0
  43. package/coverage/src/scanner/index.html +116 -0
  44. package/coverage/src/tokenizer/index.html +116 -0
  45. package/coverage/src/tokenizer/token-manager.js.html +1252 -0
  46. package/coverage/src/utils/helpers.js.html +469 -0
  47. package/coverage/src/utils/index.html +116 -0
  48. package/jest.config.js +16 -0
  49. package/package.json +5 -3
  50. package/scripts/build.js +40 -0
  51. package/src/scanner/file-scanner.js +3 -104
  52. package/src/server/api-server.js +74 -18
  53. package/src/server/views/css/structure.css +148 -0
  54. package/src/server/views/dashboard.css +176 -312
  55. package/src/server/views/dashboard.html +153 -85
  56. package/src/server/views/js/api.js +19 -2
  57. package/src/server/views/js/features/structure.js +221 -0
  58. package/src/server/views/js/handlers.js +38 -70
  59. package/src/server/views/js/main.js +60 -0
  60. package/src/server/views/js/utils.js +10 -0
  61. package/src/server/views/vg-coder/assets/icon128.png +0 -0
  62. package/src/server/views/vg-coder/assets/icon16.png +0 -0
  63. package/src/server/views/vg-coder/assets/icon48.png +0 -0
  64. package/src/server/views/vg-coder/background.js +2 -0
  65. package/src/server/views/vg-coder/background.js.LICENSE.txt +118 -0
  66. package/src/server/views/vg-coder/controller.js +1 -0
  67. package/src/server/views/vg-coder/manifest.json +58 -0
  68. package/src/server/views/vg-coder/options.css +164 -0
  69. package/src/server/views/vg-coder/options.html +48 -0
  70. package/src/server/views/vg-coder/options.js +1 -0
  71. package/src/server/views/vg-coder/rules.json +23 -0
  72. package/src/tokenizer/token-manager.js +52 -2
  73. package/vg-coder-cli-2.0.10.tgz +0 -0
  74. package/vg-coder.zip +0 -0
  75. package/vg-coder-cli-2.0.8.tgz +0 -0
@@ -0,0 +1,40 @@
1
+ const AdmZip = require('adm-zip');
2
+ const path = require('path');
3
+ const fs = require('fs-extra');
4
+
5
+ async function build() {
6
+ try {
7
+ const rootDir = path.resolve(__dirname, '..');
8
+ const zipPath = path.join(rootDir, 'vg-coder.zip');
9
+ const targetDir = path.join(rootDir, 'src', 'server', 'views', 'vg-coder');
10
+
11
+ console.log('šŸ—ļø Starting build process...');
12
+
13
+ // 1. Check if zip exists
14
+ if (!fs.existsSync(zipPath)) {
15
+ console.error('āš ļø vg-coder.zip not found at root. Skipping extension extraction.');
16
+ // We don't exit 1 here to allow build to continue if zip is missing in dev
17
+ return;
18
+ }
19
+
20
+ // 2. Clean old directory
21
+ if (fs.existsSync(targetDir)) {
22
+ console.log('🧹 Cleaning old extension directory...');
23
+ fs.removeSync(targetDir);
24
+ }
25
+
26
+ // 3. Unzip
27
+ console.log('šŸ“¦ Unzipping vg-coder.zip...');
28
+ const zip = new AdmZip(zipPath);
29
+ zip.extractAllTo(targetDir, true);
30
+
31
+ console.log(`āœ… Extension extracted to: ${targetDir}`);
32
+ console.log('šŸš€ Build completed successfully!');
33
+
34
+ } catch (error) {
35
+ console.error('āŒ Build failed:', error);
36
+ process.exit(1);
37
+ }
38
+ }
39
+
40
+ build();
@@ -106,6 +106,7 @@ class FileScanner {
106
106
 
107
107
  const node = {
108
108
  path: dirPath,
109
+ relativePath: relativePath,
109
110
  name: name,
110
111
  size: stats.size,
111
112
  type: stats.isDirectory() ? 'directory' : 'file',
@@ -148,47 +149,6 @@ class FileScanner {
148
149
  return node;
149
150
  }
150
151
 
151
- /**
152
- * Get regex for build directories and hidden files to ignore
153
- */
154
- getBuildIgnoreRegex() {
155
- // Create regex pattern for directories to ignore
156
- const ignorePatterns = [
157
- // Hidden directories (starting with .)
158
- '^\\..*',
159
-
160
- // Build directories
161
- '^build$',
162
- '^target$',
163
- '^dist$',
164
- '^out$',
165
- '^bin$',
166
-
167
- // Dependencies
168
- '^node_modules$',
169
- '^vendor$',
170
-
171
- // Temporary files
172
- '^tmp$',
173
- '^temp$',
174
-
175
- // Logs
176
- '^logs$',
177
- '^log$',
178
-
179
- // Coverage reports
180
- '^coverage$'
181
- ];
182
-
183
- // Combine all patterns into one regex
184
- const combinedPattern = ignorePatterns.join('|');
185
- return new RegExp(`(${combinedPattern})`);
186
- }
187
-
188
-
189
-
190
-
191
-
192
152
  /**
193
153
  * TrĆ­ch xuįŗ„t danh sĆ”ch files từ tree
194
154
  */
@@ -381,69 +341,8 @@ class FileScanner {
381
341
  * Tįŗ”o nį»™i dung kįŗæt hợp từ tįŗ„t cįŗ£ files
382
342
  */
383
343
  async createCombinedContent(files, options = {}) {
384
- const {
385
- includeStats = true,
386
- includeTree = true,
387
- headerTemplate = this.getDefaultHeaderTemplate(),
388
- separatorTemplate = this.getDefaultSeparatorTemplate()
389
- } = options;
390
-
391
- let content = '';
392
-
393
- // Header với thÓng tin project
394
- if (includeStats) {
395
- content += this.generateProjectHeader(files);
396
- content += '\n\n';
397
- }
398
-
399
- // CẄu trúc thư mỄc
400
- if (includeTree) {
401
- content += this.generateTreeStructure(files);
402
- content += '\n\n';
403
- }
404
-
405
- // Nį»™i dung từng file
406
- for (let i = 0; i < files.length; i++) {
407
- const file = files[i];
408
-
409
- // Header cho file
410
- content += headerTemplate
411
- .replace('{path}', file.relativePath)
412
- .replace('{name}', file.name)
413
- .replace('{extension}', file.extension || '')
414
- .replace('{size}', file.size)
415
- .replace('{lines}', file.lines);
416
-
417
- content += '\n';
418
- content += file.content;
419
- content += '\n';
420
-
421
- // Separator giữa cÔc files
422
- if (i < files.length - 1) {
423
- content += separatorTemplate;
424
- content += '\n';
425
- }
426
- }
427
-
428
- return content;
429
- }
430
-
431
- /**
432
- * Template header mįŗ·c định cho file
433
- */
434
- getDefaultHeaderTemplate() {
435
- return `
436
- ================================================================================
437
- File: {path}
438
- Size: {size} bytes | Lines: {lines}
439
- ================================================================================`;
440
- }
441
-
442
- /**
443
- * Template separator mįŗ·c định
444
- */
445
- getDefaultSeparatorTemplate() {
446
- return '\n\n';
344
+ // ... (unchanged)
345
+ return this.createCombinedContentForAI(files, options);
447
346
  }
448
347
 
449
348
  /**
@@ -29,8 +29,8 @@ class ApiServer {
29
29
  */
30
30
  setupMiddleware() {
31
31
  this.app.use(cors());
32
- this.app.use(bodyParser.json());
33
- this.app.use(bodyParser.urlencoded({ extended: true }));
32
+ this.app.use(bodyParser.json({ limit: '50mb' })); // Increase limit for large file lists
33
+ this.app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
34
34
 
35
35
  // Serve static files from views directory (CSS, JS)
36
36
  this.app.use(express.static(path.join(__dirname, 'views')));
@@ -60,10 +60,25 @@ class ApiServer {
60
60
  });
61
61
  });
62
62
 
63
+ // NEW: Get Extension Path
64
+ this.app.get('/api/extension-path', (req, res) => {
65
+ try {
66
+ const extensionPath = path.join(__dirname, 'views', 'vg-coder');
67
+ const exists = fs.existsSync(extensionPath);
68
+
69
+ res.json({
70
+ path: extensionPath,
71
+ exists: exists
72
+ });
73
+ } catch (error) {
74
+ res.status(500).json({ error: error.message });
75
+ }
76
+ });
77
+
63
78
  // Analyze endpoint - returns project.txt file
64
79
  this.app.post('/api/analyze', async (req, res) => {
65
80
  try {
66
- const { path: projectPath, options = {} } = req.body;
81
+ const { path: projectPath, options = {}, specificFiles } = req.body;
67
82
 
68
83
  if (!projectPath) {
69
84
  return res.status(400).json({
@@ -81,6 +96,9 @@ class ApiServer {
81
96
  }
82
97
 
83
98
  console.log(chalk.yellow(`Analyzing project: ${resolvedPath}`));
99
+ if (specificFiles) {
100
+ console.log(chalk.yellow(`Filtering for ${specificFiles.length} specific files`));
101
+ }
84
102
 
85
103
  // Detect project type
86
104
  const detector = new ProjectDetector(resolvedPath);
@@ -95,8 +113,15 @@ class ApiServer {
95
113
  const scanner = new FileScanner(resolvedPath, scannerOptions);
96
114
  const scanResult = await scanner.scanProject();
97
115
 
116
+ let filesToProcess = scanResult.files;
117
+
118
+ // Filter specific files if requested
119
+ if (specificFiles && Array.isArray(specificFiles) && specificFiles.length > 0) {
120
+ filesToProcess = filesToProcess.filter(file => specificFiles.includes(file.relativePath));
121
+ }
122
+
98
123
  // Create AI-friendly content
99
- const aiContent = await scanner.createCombinedContentForAI(scanResult.files, {
124
+ const aiContent = await scanner.createCombinedContentForAI(filesToProcess, {
100
125
  includeStats: true,
101
126
  includeTree: true,
102
127
  preserveLineNumbers: true
@@ -107,7 +132,7 @@ class ApiServer {
107
132
  res.setHeader('Content-Disposition', 'attachment; filename="project.txt"');
108
133
  res.send(aiContent);
109
134
 
110
- console.log(chalk.green(`āœ“ Analysis completed: ${scanResult.files.length} files`));
135
+ console.log(chalk.green(`āœ“ Analysis completed: ${filesToProcess.length} files`));
111
136
 
112
137
  } catch (error) {
113
138
  console.error(chalk.red('Error during analysis:'), error);
@@ -181,6 +206,50 @@ class ApiServer {
181
206
  }
182
207
  });
183
208
 
209
+ // Structure endpoint
210
+ this.app.get('/api/structure', async (req, res) => {
211
+ try {
212
+ const projectPath = req.query.path || '.';
213
+ const resolvedPath = path.resolve(projectPath);
214
+
215
+ // Validate path
216
+ if (!await fs.pathExists(resolvedPath)) {
217
+ return res.status(404).json({
218
+ error: `Project path does not exist: ${projectPath}`
219
+ });
220
+ }
221
+
222
+ console.log(chalk.yellow(`Analyzing structure for: ${resolvedPath}`));
223
+
224
+ // 1. Scan files
225
+ const scanner = new FileScanner(resolvedPath);
226
+ const scanResult = await scanner.scanProject();
227
+
228
+ // 2. Tokenize tree
229
+ const tokenManager = new TokenManager();
230
+ const enrichedTree = tokenManager.analyzeTree(scanResult.tree, scanResult.files);
231
+
232
+ tokenManager.cleanup();
233
+
234
+ // 3. Return result
235
+ res.json({
236
+ path: resolvedPath,
237
+ totalFiles: scanResult.files.length,
238
+ rootTokens: enrichedTree.tokens,
239
+ structure: enrichedTree
240
+ });
241
+
242
+ console.log(chalk.green(`āœ“ Structure analysis completed: ${scanResult.files.length} files`));
243
+
244
+ } catch (error) {
245
+ console.error(chalk.red('Error getting structure:'), error);
246
+ res.status(500).json({
247
+ error: 'Failed to get structure',
248
+ message: error.message
249
+ });
250
+ }
251
+ });
252
+
184
253
  // Clean endpoint
185
254
  this.app.delete('/api/clean', async (req, res) => {
186
255
  try {
@@ -285,23 +354,10 @@ class ApiServer {
285
354
  console.log(chalk.green(`\nšŸš€ VG Coder API Server started!`));
286
355
  console.log(chalk.blue(`šŸ“” Listening on: http://localhost:${this.port}`));
287
356
  console.log(chalk.cyan(`\nšŸŽØ Dashboard: http://localhost:${this.port}`));
288
- console.log(chalk.yellow(`\nšŸ“š Available endpoints:`));
289
- console.log(` GET /health - Health check`);
290
- console.log(` POST /api/analyze - Analyze project (returns project.txt)`);
291
- console.log(` GET /api/info?path=. - Get project info`);
292
- console.log(` DELETE /api/clean - Clean output directory`);
293
- console.log(` POST /api/execute - Execute bash script`);
294
- console.log(chalk.gray(`\nšŸ’” Press Ctrl+C to stop the server\n`));
295
357
  resolve();
296
358
  });
297
359
 
298
360
  this.server.on('error', (err) => {
299
- if (err.code === 'EADDRINUSE') {
300
- console.error(chalk.red(`\nāŒ Port ${this.port} is already in use!`));
301
- console.log(chalk.yellow(`Try using a different port with: vg start -p <port>\n`));
302
- } else {
303
- console.error(chalk.red('\nāŒ Server error:'), err.message);
304
- }
305
361
  reject(err);
306
362
  });
307
363
  });
@@ -0,0 +1,148 @@
1
+ /* Tree View Styles Compact */
2
+ .tree-container {
3
+ margin-top: 15px;
4
+ background: var(--ios-input-bg);
5
+ border-radius: 8px;
6
+ overflow: hidden;
7
+ border: 1px solid rgba(0, 0, 0, 0.05);
8
+ }
9
+
10
+ .tree-header {
11
+ padding: 8px 12px;
12
+ background: rgba(0, 0, 0, 0.03);
13
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
14
+ font-weight: 600;
15
+ display: flex;
16
+ justify-content: space-between;
17
+ align-items: center;
18
+ color: var(--text-primary);
19
+ font-size: 12px;
20
+ }
21
+
22
+ .tree-content {
23
+ padding: 5px;
24
+ font-family: 'SF Mono', 'Menlo', monospace;
25
+ font-size: 11px;
26
+ /* Smaller tree font */
27
+ overflow-x: auto;
28
+ max-height: 400px;
29
+ overflow-y: auto;
30
+ }
31
+
32
+ .tree-ul {
33
+ list-style: none;
34
+ padding-left: 16px;
35
+ /* Reduced indentation */
36
+ margin: 0;
37
+ border-left: 1px solid var(--ios-separator);
38
+ }
39
+
40
+ /* Root level shouldn't have border */
41
+ .tree-content>.tree-ul {
42
+ border-left: none;
43
+ padding-left: 0;
44
+ }
45
+
46
+ .tree-li {
47
+ margin: 1px 0;
48
+ /* Compact spacing */
49
+ position: relative;
50
+ }
51
+
52
+ .tree-item-row {
53
+ display: flex;
54
+ align-items: center;
55
+ padding: 2px 6px;
56
+ /* Compact row padding */
57
+ border-radius: 4px;
58
+ cursor: pointer;
59
+ transition: background 0.1s;
60
+ line-height: 1.2;
61
+ }
62
+
63
+ .tree-item-row:hover {
64
+ background: rgba(0, 0, 0, 0.05);
65
+ }
66
+
67
+ /* Checkbox Style */
68
+ .tree-checkbox {
69
+ margin-right: 6px;
70
+ cursor: pointer;
71
+ width: 14px;
72
+ /* Smaller checkbox */
73
+ height: 14px;
74
+ accent-color: var(--ios-blue);
75
+ }
76
+
77
+ .tree-icon {
78
+ margin-right: 6px;
79
+ font-size: 12px;
80
+ width: 14px;
81
+ text-align: center;
82
+ }
83
+
84
+ .tree-name {
85
+ flex: 1;
86
+ white-space: nowrap;
87
+ overflow: hidden;
88
+ text-overflow: ellipsis;
89
+ margin-right: 8px;
90
+ color: var(--text-primary);
91
+ }
92
+
93
+ /* Token Badges */
94
+ .token-badge {
95
+ font-size: 9px;
96
+ /* Very small badge */
97
+ padding: 1px 4px;
98
+ border-radius: 3px;
99
+ font-weight: 600;
100
+ min-width: 30px;
101
+ text-align: center;
102
+ }
103
+
104
+ .token-low {
105
+ background: rgba(52, 199, 89, 0.15);
106
+ color: var(--ios-green);
107
+ }
108
+
109
+ /* < 2k */
110
+ .token-med {
111
+ background: rgba(255, 149, 0, 0.15);
112
+ color: #FF9500;
113
+ }
114
+
115
+ /* 2k - 5k */
116
+ .token-high {
117
+ background: rgba(255, 59, 48, 0.15);
118
+ color: var(--ios-red);
119
+ }
120
+
121
+ /* > 5k */
122
+
123
+ /* Folder toggle states */
124
+ .tree-li>.tree-ul {
125
+ display: block;
126
+ /* Default expanded */
127
+ }
128
+
129
+ .tree-li.collapsed>.tree-ul {
130
+ display: none;
131
+ }
132
+
133
+ .arrow {
134
+ display: inline-block;
135
+ width: 10px;
136
+ font-size: 8px;
137
+ color: var(--text-secondary);
138
+ transition: transform 0.2s;
139
+ margin-right: 2px;
140
+ }
141
+
142
+ .tree-li.collapsed>.tree-item-row .arrow {
143
+ transform: rotate(-90deg);
144
+ }
145
+
146
+ .tree-li:not(.has-children) .arrow {
147
+ visibility: hidden;
148
+ }