vg-coder-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # VG Coder CLI
2
+
3
+ 🚀 **CLI tool để phân tích dự án, nối file mã nguồn, đếm token và xuất HTML** với syntax highlighting và copy functionality.
4
+
5
+ ## ✨ Tính năng
6
+
7
+ - 🔍 **Phát hiện loại dự án**: Tự động nhận diện Angular, Spring Boot, React, Vue, Node.js, Python, Java, .NET
8
+ - 📁 **Xử lý .gitignore**: Tuân thủ chuẩn Git với multi-level ignore rules
9
+ - 📄 **Scan và nối file**: Quét toàn bộ dự án và nối file mã nguồn
10
+ - 🧮 **Đếm token**: Sử dụng tiktoken để đếm token chính xác cho AI models
11
+ - ✂️ **Chia nhỏ nội dung**: Smart chunking với preserve structure
12
+ - 🌐 **Xuất HTML**: Tạo HTML với syntax highlighting và copy buttons
13
+ - 🎨 **Syntax Highlighting**: Hỗ trợ nhiều ngôn ngữ lập trình
14
+ - 📋 **Copy to Clipboard**: Dễ dàng copy code với một click
15
+
16
+ ## 📦 Cài đặt
17
+
18
+ ### Cài đặt từ NPM (Recommended)
19
+ ```bash
20
+ # Cài đặt global
21
+ npm install -g vg-coder-cli
22
+
23
+ # Hoặc cài đặt local
24
+ npm install vg-coder-cli
25
+ ```
26
+
27
+ ### Cài đặt từ source
28
+ ```bash
29
+ # Clone repository
30
+ git clone <repository-url>
31
+ cd vg-coder-cli
32
+
33
+ # Cài đặt dependencies
34
+ npm install
35
+
36
+ # Cấp quyền thực thi (nếu cần)
37
+ chmod +x bin/vg-coder.js
38
+ ```
39
+
40
+ ## 🚀 Sử dụng
41
+
42
+ ### Phân tích dự án
43
+ ```bash
44
+ # Nếu cài global
45
+ vg-coder analyze
46
+
47
+ # Nếu cài local
48
+ npx vg-coder analyze
49
+
50
+ # Phân tích dự án khác
51
+ vg-coder analyze /path/to/project
52
+
53
+ # Với options tùy chỉnh
54
+ vg-coder analyze /path/to/project --max-tokens 8192 --output ./my-output --theme monokai
55
+ ```
56
+
57
+ ### Xem thông tin dự án
58
+ ```bash
59
+ # Thông tin dự án hiện tại
60
+ vg-coder info
61
+
62
+ # Thông tin dự án khác
63
+ vg-coder info /path/to/project
64
+ ```
65
+
66
+ ### Xóa output
67
+ ```bash
68
+ # Xóa output mặc định
69
+ node src/index.js clean
70
+
71
+ # Xóa output tùy chỉnh
72
+ node src/index.js clean --output ./my-output
73
+ ```
74
+
75
+ ## ⚙️ Options
76
+
77
+ | Option | Mô tả | Default |
78
+ |--------|-------|---------|
79
+ | `--max-tokens <number>` | Số token tối đa mỗi chunk | 8000 |
80
+ | `--model <model>` | Model AI để đếm token | gpt-4 |
81
+ | `--output <path>` | Thư mục output | ./vg-output |
82
+ | `--extensions <list>` | Danh sách extensions (comma-separated) | Auto-detect |
83
+ | `--include-hidden` | Bao gồm file ẩn | false |
84
+ | `--no-structure` | Không ưu tiên giữ cấu trúc file | false |
85
+ | `--theme <theme>` | Theme cho syntax highlighting | github |
86
+
87
+ ## 📋 Ví dụ chi tiết
88
+
89
+ ### Phân tích dự án Angular
90
+ ```bash
91
+ node src/index.js analyze ./my-angular-app --max-tokens 6000 --theme monokai
92
+ ```
93
+
94
+ ### Phân tích với extensions tùy chỉnh
95
+ ```bash
96
+ node src/index.js analyze ./my-project --extensions "js,ts,vue,css" --include-hidden
97
+ ```
98
+
99
+ ### Xem thông tin chi tiết
100
+ ```bash
101
+ node src/index.js info ./my-project
102
+ # Output:
103
+ # 📁 Project Information:
104
+ # Path: /path/to/my-project
105
+ # Primary Type: nodejs
106
+ #
107
+ # Detected Technologies:
108
+ # nodejs: high confidence
109
+ #
110
+ # 📊 File Statistics:
111
+ # Total Files: 25
112
+ # Total Size: 156.7 KB
113
+ # Total Lines: 4,523
114
+ # Extensions: js, ts, json, md
115
+ ```
116
+
117
+ ## 🧪 Testing
118
+
119
+ ```bash
120
+ # Chạy tất cả tests
121
+ npm test
122
+
123
+ # Chạy tests với coverage
124
+ npm run test:coverage
125
+
126
+ # Chạy specific test
127
+ npm test -- --testNamePattern="project detection"
128
+ ```
129
+
130
+ ## 📁 Cấu trúc Output
131
+
132
+ ```
133
+ vg-output/
134
+ ├── index.html # Trang chính với navigation
135
+ ├── combined.html # Tất cả code trong một file
136
+ ├── chunks/ # Các chunk riêng biệt
137
+ │ ├── chunk-1.html
138
+ │ ├── chunk-2.html
139
+ │ └── ...
140
+ └── assets/ # CSS, JS, themes
141
+ ├── styles.css
142
+ ├── scripts.js
143
+ └── highlight.css
144
+ ```
145
+
146
+ ## 🎯 Các loại dự án được hỗ trợ
147
+
148
+ - **Frontend**: Angular, React, Vue.js, Svelte
149
+ - **Backend**: Node.js, Spring Boot, Python, .NET
150
+ - **Mobile**: React Native, Flutter
151
+ - **Languages**: JavaScript, TypeScript, Java, Python, C#, Go, Rust
152
+ - **Config**: JSON, YAML, XML, TOML
153
+
154
+ ## 🔧 Tùy chỉnh
155
+
156
+ ### Extensions mặc định
157
+ Tool tự động detect extensions phù hợp với loại dự án:
158
+ - **Web**: .js, .jsx, .ts, .tsx, .vue, .html, .css, .scss
159
+ - **Backend**: .java, .py, .cs, .go, .rs, .php
160
+ - **Config**: .json, .yaml, .xml, .toml, .env
161
+
162
+ ### Themes có sẵn
163
+ - github (default)
164
+ - monokai
165
+ - atom-one-dark
166
+ - vs2015
167
+ - rainbow
168
+
169
+ ## 🤝 Đóng góp
170
+
171
+ 1. Fork repository
172
+ 2. Tạo feature branch (`git checkout -b feature/amazing-feature`)
173
+ 3. Commit changes (`git commit -m 'Add amazing feature'`)
174
+ 4. Push to branch (`git push origin feature/amazing-feature`)
175
+ 5. Tạo Pull Request
176
+
177
+ ## 📄 License
178
+
179
+ MIT License - xem file [LICENSE](LICENSE) để biết thêm chi tiết.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * VG Coder CLI Entry Point
5
+ */
6
+
7
+ const VGCoderCLI = require('../src/index');
8
+
9
+ // Create and run CLI
10
+ const cli = new VGCoderCLI();
11
+ cli.run();
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "vg-coder-cli",
3
+ "version": "1.0.0",
4
+ "description": "🚀 CLI tool to analyze projects, concatenate source files, count tokens, and export HTML with syntax highlighting and copy functionality",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "vg-coder": "./bin/vg-coder.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node src/index.js",
11
+ "test": "jest",
12
+ "test:analyze": "node src/index.js analyze hdb-signature-service --max-tokens 8192 --theme monokai",
13
+ "test:watch": "jest --watch",
14
+ "dev": "nodemon src/index.js"
15
+ },
16
+ "keywords": [
17
+ "cli",
18
+ "code-analysis",
19
+ "token-counter",
20
+ "ai-helper",
21
+ "gitignore",
22
+ "html-export",
23
+ "syntax-highlighting",
24
+ "project-analyzer",
25
+ "source-code",
26
+ "tiktoken",
27
+ "spring-boot",
28
+ "angular",
29
+ "react",
30
+ "vue",
31
+ "java",
32
+ "javascript",
33
+ "typescript"
34
+ ],
35
+ "author": "VG Coder",
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/vg-coder/vg-coder-cli.git"
40
+ },
41
+ "bugs": {
42
+ "url": "https://github.com/vg-coder/vg-coder-cli/issues"
43
+ },
44
+ "homepage": "https://github.com/vg-coder/vg-coder-cli#readme",
45
+ "dependencies": {
46
+ "commander": "^11.1.0",
47
+ "directory-tree": "^3.5.1",
48
+ "tiktoken": "^1.0.10",
49
+ "highlight.js": "^11.9.0",
50
+ "ignore": "^5.3.0",
51
+ "fs-extra": "^11.2.0",
52
+ "path": "^0.12.7",
53
+ "chalk": "^4.1.2",
54
+ "ora": "^5.4.1"
55
+ },
56
+ "devDependencies": {
57
+ "jest": "^29.7.0",
58
+ "nodemon": "^3.0.2",
59
+ "@types/jest": "^29.5.8"
60
+ },
61
+ "engines": {
62
+ "node": ">=16.0.0"
63
+ }
64
+ }
@@ -0,0 +1,333 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ /**
5
+ * Phát hiện loại dự án dựa trên các file cấu hình
6
+ */
7
+ class ProjectDetector {
8
+ constructor(projectPath) {
9
+ this.projectPath = projectPath;
10
+ }
11
+
12
+ /**
13
+ * Phát hiện tất cả loại dự án có thể
14
+ * @returns {Object} Object chứa thông tin các loại dự án được phát hiện
15
+ */
16
+ async detectAll() {
17
+ const results = {
18
+ angular: await this.detectAngular(),
19
+ springBoot: await this.detectSpringBoot(),
20
+ react: await this.detectReact(),
21
+ vue: await this.detectVue(),
22
+ nodejs: await this.detectNodeJS(),
23
+ java: await this.detectJava(),
24
+ python: await this.detectPython(),
25
+ dotnet: await this.detectDotNet()
26
+ };
27
+
28
+ // Lọc ra các loại dự án được phát hiện
29
+ const detected = Object.entries(results)
30
+ .filter(([_, info]) => info.detected)
31
+ .reduce((acc, [type, info]) => {
32
+ acc[type] = info;
33
+ return acc;
34
+ }, {});
35
+
36
+ return {
37
+ detected,
38
+ primary: this.determinePrimaryType(detected),
39
+ all: results
40
+ };
41
+ }
42
+
43
+ /**
44
+ * Phát hiện Angular project
45
+ */
46
+ async detectAngular() {
47
+ try {
48
+ const packageJsonPath = path.join(this.projectPath, 'package.json');
49
+ const angularJsonPath = path.join(this.projectPath, 'angular.json');
50
+
51
+ if (await fs.pathExists(packageJsonPath)) {
52
+ const packageJson = await fs.readJson(packageJsonPath);
53
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
54
+
55
+ const hasAngularCore = deps['@angular/core'];
56
+ const hasAngularCli = deps['@angular/cli'];
57
+ const hasAngularJson = await fs.pathExists(angularJsonPath);
58
+
59
+ if (hasAngularCore || hasAngularCli || hasAngularJson) {
60
+ return {
61
+ detected: true,
62
+ confidence: hasAngularCore && hasAngularJson ? 'high' : 'medium',
63
+ version: hasAngularCore || 'unknown',
64
+ indicators: {
65
+ packageJson: !!hasAngularCore || !!hasAngularCli,
66
+ angularJson: hasAngularJson,
67
+ dependencies: Object.keys(deps).filter(dep => dep.startsWith('@angular/'))
68
+ }
69
+ };
70
+ }
71
+ }
72
+ } catch (error) {
73
+ // Ignore errors
74
+ }
75
+
76
+ return { detected: false };
77
+ }
78
+
79
+ /**
80
+ * Phát hiện Spring Boot project
81
+ */
82
+ async detectSpringBoot() {
83
+ try {
84
+ const pomPath = path.join(this.projectPath, 'pom.xml');
85
+ const gradlePath = path.join(this.projectPath, 'build.gradle');
86
+ const gradleKtsPath = path.join(this.projectPath, 'build.gradle.kts');
87
+
88
+ // Kiểm tra Maven (pom.xml)
89
+ if (await fs.pathExists(pomPath)) {
90
+ const pomContent = await fs.readFile(pomPath, 'utf8');
91
+ if (pomContent.includes('spring-boot-starter') || pomContent.includes('org.springframework.boot')) {
92
+ return {
93
+ detected: true,
94
+ confidence: 'high',
95
+ buildTool: 'maven',
96
+ indicators: {
97
+ pomXml: true,
98
+ springBootStarter: pomContent.includes('spring-boot-starter')
99
+ }
100
+ };
101
+ }
102
+ }
103
+
104
+ // Kiểm tra Gradle
105
+ for (const gradleFile of [gradlePath, gradleKtsPath]) {
106
+ if (await fs.pathExists(gradleFile)) {
107
+ const gradleContent = await fs.readFile(gradleFile, 'utf8');
108
+ if (gradleContent.includes('spring-boot') || gradleContent.includes('org.springframework.boot')) {
109
+ return {
110
+ detected: true,
111
+ confidence: 'high',
112
+ buildTool: gradleFile.endsWith('.kts') ? 'gradle-kotlin' : 'gradle',
113
+ indicators: {
114
+ buildGradle: true,
115
+ springBootPlugin: gradleContent.includes('org.springframework.boot')
116
+ }
117
+ };
118
+ }
119
+ }
120
+ }
121
+ } catch (error) {
122
+ // Ignore errors
123
+ }
124
+
125
+ return { detected: false };
126
+ }
127
+
128
+ /**
129
+ * Phát hiện React project
130
+ */
131
+ async detectReact() {
132
+ try {
133
+ const packageJsonPath = path.join(this.projectPath, 'package.json');
134
+ if (await fs.pathExists(packageJsonPath)) {
135
+ const packageJson = await fs.readJson(packageJsonPath);
136
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
137
+
138
+ if (deps.react) {
139
+ return {
140
+ detected: true,
141
+ confidence: 'high',
142
+ version: deps.react,
143
+ indicators: {
144
+ react: true,
145
+ reactDom: !!deps['react-dom'],
146
+ nextJs: !!deps.next,
147
+ createReactApp: !!deps['react-scripts']
148
+ }
149
+ };
150
+ }
151
+ }
152
+ } catch (error) {
153
+ // Ignore errors
154
+ }
155
+
156
+ return { detected: false };
157
+ }
158
+
159
+ /**
160
+ * Phát hiện Vue project
161
+ */
162
+ async detectVue() {
163
+ try {
164
+ const packageJsonPath = path.join(this.projectPath, 'package.json');
165
+ if (await fs.pathExists(packageJsonPath)) {
166
+ const packageJson = await fs.readJson(packageJsonPath);
167
+ const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
168
+
169
+ if (deps.vue) {
170
+ return {
171
+ detected: true,
172
+ confidence: 'high',
173
+ version: deps.vue,
174
+ indicators: {
175
+ vue: true,
176
+ vueRouter: !!deps['vue-router'],
177
+ vuex: !!deps.vuex,
178
+ nuxt: !!deps.nuxt
179
+ }
180
+ };
181
+ }
182
+ }
183
+ } catch (error) {
184
+ // Ignore errors
185
+ }
186
+
187
+ return { detected: false };
188
+ }
189
+
190
+ /**
191
+ * Phát hiện Node.js project
192
+ */
193
+ async detectNodeJS() {
194
+ try {
195
+ const packageJsonPath = path.join(this.projectPath, 'package.json');
196
+ return {
197
+ detected: await fs.pathExists(packageJsonPath),
198
+ confidence: 'high',
199
+ indicators: {
200
+ packageJson: await fs.pathExists(packageJsonPath)
201
+ }
202
+ };
203
+ } catch (error) {
204
+ return { detected: false };
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Phát hiện Java project
210
+ */
211
+ async detectJava() {
212
+ try {
213
+ const pomPath = path.join(this.projectPath, 'pom.xml');
214
+ const gradlePath = path.join(this.projectPath, 'build.gradle');
215
+ const gradleKtsPath = path.join(this.projectPath, 'build.gradle.kts');
216
+
217
+ const hasPom = await fs.pathExists(pomPath);
218
+ const hasGradle = await fs.pathExists(gradlePath) || await fs.pathExists(gradleKtsPath);
219
+
220
+ if (hasPom || hasGradle) {
221
+ return {
222
+ detected: true,
223
+ confidence: 'high',
224
+ buildTool: hasPom ? 'maven' : 'gradle',
225
+ indicators: {
226
+ maven: hasPom,
227
+ gradle: hasGradle
228
+ }
229
+ };
230
+ }
231
+ } catch (error) {
232
+ // Ignore errors
233
+ }
234
+
235
+ return { detected: false };
236
+ }
237
+
238
+ /**
239
+ * Phát hiện Python project
240
+ */
241
+ async detectPython() {
242
+ try {
243
+ const requirementsPath = path.join(this.projectPath, 'requirements.txt');
244
+ const pipfilePath = path.join(this.projectPath, 'Pipfile');
245
+ const pyprojectPath = path.join(this.projectPath, 'pyproject.toml');
246
+ const setupPyPath = path.join(this.projectPath, 'setup.py');
247
+
248
+ const hasRequirements = await fs.pathExists(requirementsPath);
249
+ const hasPipfile = await fs.pathExists(pipfilePath);
250
+ const hasPyproject = await fs.pathExists(pyprojectPath);
251
+ const hasSetupPy = await fs.pathExists(setupPyPath);
252
+
253
+ if (hasRequirements || hasPipfile || hasPyproject || hasSetupPy) {
254
+ return {
255
+ detected: true,
256
+ confidence: 'high',
257
+ indicators: {
258
+ requirements: hasRequirements,
259
+ pipfile: hasPipfile,
260
+ pyproject: hasPyproject,
261
+ setupPy: hasSetupPy
262
+ }
263
+ };
264
+ }
265
+ } catch (error) {
266
+ // Ignore errors
267
+ }
268
+
269
+ return { detected: false };
270
+ }
271
+
272
+ /**
273
+ * Phát hiện .NET project
274
+ */
275
+ async detectDotNet() {
276
+ try {
277
+ const csprojFiles = await this.findFilesByExtension('.csproj');
278
+ const vbprojFiles = await this.findFilesByExtension('.vbproj');
279
+ const fsprojFiles = await this.findFilesByExtension('.fsproj');
280
+ const slnFiles = await this.findFilesByExtension('.sln');
281
+
282
+ const hasProjectFiles = csprojFiles.length > 0 || vbprojFiles.length > 0 || fsprojFiles.length > 0;
283
+ const hasSolution = slnFiles.length > 0;
284
+
285
+ if (hasProjectFiles || hasSolution) {
286
+ return {
287
+ detected: true,
288
+ confidence: 'high',
289
+ indicators: {
290
+ csproj: csprojFiles.length,
291
+ vbproj: vbprojFiles.length,
292
+ fsproj: fsprojFiles.length,
293
+ solution: slnFiles.length
294
+ }
295
+ };
296
+ }
297
+ } catch (error) {
298
+ // Ignore errors
299
+ }
300
+
301
+ return { detected: false };
302
+ }
303
+
304
+ /**
305
+ * Tìm files theo extension
306
+ */
307
+ async findFilesByExtension(extension) {
308
+ try {
309
+ const files = await fs.readdir(this.projectPath);
310
+ return files.filter(file => file.endsWith(extension));
311
+ } catch (error) {
312
+ return [];
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Xác định loại dự án chính
318
+ */
319
+ determinePrimaryType(detected) {
320
+ const priorities = ['angular', 'springBoot', 'react', 'vue', 'nodejs', 'java', 'python', 'dotnet'];
321
+
322
+ for (const type of priorities) {
323
+ if (detected[type] && detected[type].confidence === 'high') {
324
+ return type;
325
+ }
326
+ }
327
+
328
+ // Fallback to first detected
329
+ return Object.keys(detected)[0] || 'unknown';
330
+ }
331
+ }
332
+
333
+ module.exports = ProjectDetector;