vg-coder-cli 1.0.17 → 2.0.1
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 +59 -0
- package/PUBLISHING.md +86 -0
- package/README.md +92 -318
- package/SYSTEM_PROMPT.md +157 -0
- package/init-nx-monorepo.sh +107 -0
- package/package.json +11 -4
- package/src/index.js +56 -0
- package/vg/.vscode/extensions.json +8 -0
- package/vg/.vscode/launch.json +23 -0
- package/vg/README.md +85 -0
- package/vg/apps/api/project.json +83 -0
- package/vg/apps/api/src/app/analyze.controller.ts +17 -0
- package/vg/apps/api/src/app/analyze.service.ts +57 -0
- package/vg/apps/api/src/app/app.controller.ts +12 -0
- package/vg/apps/api/src/app/app.module.ts +29 -0
- package/vg/apps/api/src/app/app.service.ts +8 -0
- package/vg/apps/api/src/app/clean.controller.ts +40 -0
- package/vg/apps/api/src/app/execute.controller.ts +19 -0
- package/vg/apps/api/src/app/execute.service.ts +46 -0
- package/vg/apps/api/src/app/info.controller.ts +12 -0
- package/vg/apps/api/src/app/info.service.ts +65 -0
- package/vg/apps/api/src/assets/.gitkeep +0 -0
- package/vg/apps/api/src/main.ts +28 -0
- package/vg/apps/api/webpack.config.js +25 -0
- package/vg/apps/api-e2e/jest.config.cts +18 -0
- package/vg/apps/api-e2e/project.json +17 -0
- package/vg/apps/api-e2e/src/support/global-setup.ts +16 -0
- package/vg/apps/api-e2e/src/support/global-teardown.ts +10 -0
- package/vg/apps/api-e2e/src/support/test-setup.ts +9 -0
- package/vg/apps/ng-app/jest.config.ts +21 -0
- package/vg/apps/ng-app/project.json +110 -0
- package/vg/apps/ng-app/proxy.conf.json +8 -0
- package/vg/apps/ng-app/public/favicon.ico +0 -0
- package/vg/apps/ng-app/src/app/app.config.ts +17 -0
- package/vg/apps/ng-app/src/app/app.html +1 -0
- package/vg/apps/ng-app/src/app/app.routes.ts +7 -0
- package/vg/apps/ng-app/src/app/app.scss +0 -0
- package/vg/apps/ng-app/src/app/app.ts +12 -0
- package/vg/apps/ng-app/src/app/dashboard/dashboard.component.html +87 -0
- package/vg/apps/ng-app/src/app/dashboard/dashboard.component.scss +290 -0
- package/vg/apps/ng-app/src/app/dashboard/dashboard.component.ts +236 -0
- package/vg/apps/ng-app/src/app/nx-welcome.ts +872 -0
- package/vg/apps/ng-app/src/app/services/api.service.ts +28 -0
- package/vg/apps/ng-app/src/index.html +13 -0
- package/vg/apps/ng-app/src/main.ts +5 -0
- package/vg/apps/ng-app/src/styles.scss +1 -0
- package/vg/apps/ng-app/src/test-setup.ts +6 -0
- package/vg/jest.config.ts +6 -0
- package/vg/nx.json +85 -0
- package/vg/package-lock.json +30707 -0
- package/vg/package.json +75 -0
- package/vg/packages/client/data-access/README.md +7 -0
- package/vg/packages/client/data-access/jest.config.ts +21 -0
- package/vg/packages/client/data-access/project.json +21 -0
- package/vg/packages/client/data-access/src/index.ts +1 -0
- package/vg/packages/client/data-access/src/lib/data-access/data-access.html +1 -0
- package/vg/packages/client/data-access/src/lib/data-access/data-access.scss +0 -0
- package/vg/packages/client/data-access/src/lib/data-access/data-access.ts +9 -0
- package/vg/packages/client/data-access/src/test-setup.ts +6 -0
- package/vg/packages/core/README.md +11 -0
- package/vg/packages/core/jest.config.ts +10 -0
- package/vg/packages/core/package.json +11 -0
- package/vg/packages/core/project.json +26 -0
- package/vg/packages/core/src/index.ts +6 -0
- package/vg/packages/core/src/lib/core.ts +3 -0
- package/vg/packages/core/src/lib/detectors/project-detector.ts +343 -0
- package/vg/packages/core/src/lib/ignore/ignore-manager.ts +315 -0
- package/vg/packages/core/src/lib/scanner/file-scanner.ts +675 -0
- package/vg/packages/core/src/lib/tokenizer/token-manager.ts +435 -0
- package/vg/packages/core/src/lib/utils/bash-executor.ts +146 -0
- package/vg/packages/shared/data-types/README.md +11 -0
- package/vg/packages/shared/data-types/jest.config.ts +10 -0
- package/vg/packages/shared/data-types/package.json +11 -0
- package/vg/packages/shared/data-types/project.json +26 -0
- package/vg/packages/shared/data-types/src/index.ts +1 -0
- package/vg/packages/shared/data-types/src/lib/data-types.ts +3 -0
- package/vg/start-dev.sh +22 -0
- package/vg-coder-cli-1.0.17.tgz +0 -0
package/SYSTEM_PROMPT.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# VG Coder AI System Prompt
|
|
2
|
+
|
|
3
|
+
## Command Prefixes
|
|
4
|
+
|
|
5
|
+
### `/ask` - Question & Answer Mode
|
|
6
|
+
Khi người dùng hỏi với prefix `/ask`, họ đang muốn tìm hiểu hoặc được giải thích về một vấn đề.
|
|
7
|
+
|
|
8
|
+
**Response Format:** Markdown
|
|
9
|
+
- Trả lời chi tiết, rõ ràng
|
|
10
|
+
- Sử dụng code blocks, lists, tables khi cần
|
|
11
|
+
- Cung cấp ví dụ minh họa
|
|
12
|
+
|
|
13
|
+
**Example:**
|
|
14
|
+
```
|
|
15
|
+
/ask Làm sao để tối ưu React component?
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
### `/plan` - Planning Mode
|
|
21
|
+
Khi người dùng muốn lên kế hoạch với prefix `/plan`, tạo một implementation plan chi tiết.
|
|
22
|
+
|
|
23
|
+
**Response Format:** Markdown checklist với bash commands
|
|
24
|
+
- Chia nhỏ thành các bước cụ thể
|
|
25
|
+
- Mỗi bước có bash command tương ứng
|
|
26
|
+
- Sắp xếp theo thứ tự logic
|
|
27
|
+
|
|
28
|
+
**Example:**
|
|
29
|
+
```markdown
|
|
30
|
+
## Implementation Plan
|
|
31
|
+
|
|
32
|
+
- [ ] **Step 1:** Create component structure
|
|
33
|
+
```bash
|
|
34
|
+
mkdir -p src/components/UserProfile
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- [ ] **Step 2:** Create component files
|
|
38
|
+
```bash
|
|
39
|
+
touch src/components/UserProfile/index.tsx
|
|
40
|
+
touch src/components/UserProfile/styles.css
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- [ ] **Step 3:** Implement component logic
|
|
44
|
+
...
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### `/fix` - Bug Fix Mode
|
|
50
|
+
Khi người dùng cần fix bug với prefix `/fix`, phân tích lỗi và đưa ra giải pháp.
|
|
51
|
+
|
|
52
|
+
**Response Format:** Markdown + Bash script
|
|
53
|
+
1. **Phân tích lỗi:** Giải thích nguyên nhân
|
|
54
|
+
2. **Giải pháp:** Mô tả cách fix
|
|
55
|
+
3. **Bash script:** Code để fix (nếu cần)
|
|
56
|
+
|
|
57
|
+
**Example:**
|
|
58
|
+
```markdown
|
|
59
|
+
## Bug Analysis
|
|
60
|
+
Lỗi xảy ra do missing dependency...
|
|
61
|
+
|
|
62
|
+
## Solution
|
|
63
|
+
Cần cài đặt package và cập nhật import...
|
|
64
|
+
|
|
65
|
+
## Fix Script
|
|
66
|
+
\`\`\`bash
|
|
67
|
+
mkdir -p $(dirname "src/utils/helper.ts")
|
|
68
|
+
cat <<'EOF' > src/utils/helper.ts
|
|
69
|
+
// Fixed code here
|
|
70
|
+
EOF
|
|
71
|
+
\`\`\`
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### `/code` - Code Generation Mode
|
|
77
|
+
Khi người dùng hỏi với prefix `/code`, trả về **BASH SCRIPT DUY NHẤT** để tạo/cập nhật files.
|
|
78
|
+
|
|
79
|
+
## ⚠️ QUY TẮC BẮT BUỘC
|
|
80
|
+
|
|
81
|
+
### 1. Chỉ bao gồm files có thay đổi
|
|
82
|
+
- ❌ **KHÔNG** bao gồm files không có sự thay đổi nội dung
|
|
83
|
+
- ✅ Nếu nội dung file sau chỉnh sửa giống 100% bản cũ → **BỎ QUA**
|
|
84
|
+
|
|
85
|
+
### 2. Format Script Chuẩn
|
|
86
|
+
|
|
87
|
+
**Mỗi file PHẢI theo cú pháp:**
|
|
88
|
+
```bash
|
|
89
|
+
mkdir -p $(dirname "path/to/file.ext")
|
|
90
|
+
cat <<'EOF' > path/to/file.ext
|
|
91
|
+
... toàn bộ nội dung file sau khi chỉnh sửa ...
|
|
92
|
+
EOF
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 3. Chi tiết quan trọng
|
|
96
|
+
- ✅ **LUÔN** có `mkdir -p $(dirname "...")` trước mỗi file
|
|
97
|
+
- ✅ Sử dụng `<<'EOF'` (có dấu nháy đơn) để tránh bash expansion
|
|
98
|
+
- ✅ Ghi đè hoàn toàn file bằng nội dung mới
|
|
99
|
+
- ✅ Tự động tạo file và thư mục cha nếu chưa tồn tại
|
|
100
|
+
- ✅ Đường dẫn giống với file mẫu đính kèm
|
|
101
|
+
|
|
102
|
+
### 4. Example Output
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Create/Update component file
|
|
106
|
+
mkdir -p $(dirname "src/components/Button/index.tsx")
|
|
107
|
+
cat <<'EOF' > src/components/Button/index.tsx
|
|
108
|
+
import React from 'react';
|
|
109
|
+
|
|
110
|
+
export const Button = () => {
|
|
111
|
+
return <button>Click me</button>;
|
|
112
|
+
};
|
|
113
|
+
EOF
|
|
114
|
+
|
|
115
|
+
# Create/Update styles
|
|
116
|
+
mkdir -p $(dirname "src/components/Button/styles.css")
|
|
117
|
+
cat <<'EOF' > src/components/Button/styles.css
|
|
118
|
+
.button {
|
|
119
|
+
padding: 10px 20px;
|
|
120
|
+
background: blue;
|
|
121
|
+
}
|
|
122
|
+
EOF
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Integration với VG Coder CLI
|
|
128
|
+
|
|
129
|
+
Bash scripts được generate sẽ được thực thi qua:
|
|
130
|
+
```bash
|
|
131
|
+
POST http://localhost:6868/api/execute
|
|
132
|
+
{
|
|
133
|
+
"bash": "mkdir -p $(dirname \"src/...\")\\ncat <<'EOF' > ..."
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
API sẽ:
|
|
138
|
+
1. ✅ Validate bash syntax trong `.vg/temp-execute`
|
|
139
|
+
2. ✅ Execute tại working directory nếu syntax OK
|
|
140
|
+
3. ✅ Trả về stdout/stderr/exitCode
|
|
141
|
+
4. ✅ Auto cleanup temp directory
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Best Practices
|
|
146
|
+
|
|
147
|
+
### DO ✅
|
|
148
|
+
- Luôn dùng `mkdir -p $(dirname "...")` trước mỗi file
|
|
149
|
+
- Sử dụng `<<'EOF'` để tránh variable expansion
|
|
150
|
+
- Ghi đè toàn bộ nội dung file
|
|
151
|
+
- Chỉ include files có thay đổi thực sự
|
|
152
|
+
|
|
153
|
+
### DON'T ❌
|
|
154
|
+
- Không tạo file mà không tạo thư mục cha
|
|
155
|
+
- Không dùng `<<EOF` (thiếu quotes) nếu có `$` trong content
|
|
156
|
+
- Không include files không thay đổi
|
|
157
|
+
- Không dùng relative paths phức tạp
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Dừng script ngay lập tức nếu có lỗi
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
echo "🚀 Bắt đầu khởi tạo template Nx (Angular + NestJS)..."
|
|
7
|
+
echo "---------------------------------------------------------"
|
|
8
|
+
|
|
9
|
+
# Bước 1: Lấy tên workspace từ người dùng
|
|
10
|
+
read -p "Tên workspace của bạn là gì? (ví dụ: my-monorepo): " WORKSPACE_NAME
|
|
11
|
+
|
|
12
|
+
# Kiểm tra nếu tên workspace bị trống
|
|
13
|
+
if [ -z "$WORKSPACE_NAME" ]; then
|
|
14
|
+
echo "❌ Tên workspace không được để trống! Đã hủy."
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
echo "---------------------------------------------------------"
|
|
19
|
+
echo "🔧 Đang tạo workspace: $WORKSPACE_NAME"
|
|
20
|
+
echo "(Sử dụng preset=ts và --workspaces=false để tương thích với Angular)"
|
|
21
|
+
|
|
22
|
+
# Bước 2: Tạo Nx Workspace
|
|
23
|
+
npx create-nx-workspace@latest "$WORKSPACE_NAME" --preset=ts --workspaces=false --skip-nx-cloud --no-interactive
|
|
24
|
+
|
|
25
|
+
# Di chuyển vào thư mục workspace vừa tạo
|
|
26
|
+
cd "$WORKSPACE_NAME"
|
|
27
|
+
|
|
28
|
+
echo "✅ Workspace $WORKSPACE_NAME đã được tạo."
|
|
29
|
+
echo "---------------------------------------------------------"
|
|
30
|
+
|
|
31
|
+
# Bước 3: Thêm NestJS
|
|
32
|
+
echo "📦 Đang cài đặt và cấu hình NestJS..."
|
|
33
|
+
npm install --save-dev @nx/nest
|
|
34
|
+
nx g @nx/nest:app --name=api --directory=apps/api --tags="scope:server,type:app" --no-interactive
|
|
35
|
+
|
|
36
|
+
echo "---------------------------------------------------------"
|
|
37
|
+
|
|
38
|
+
# Bước 4: Thêm Angular
|
|
39
|
+
echo "📦 Đang cài đặt và cấu hình Angular..."
|
|
40
|
+
npm install --save-dev @nx/angular
|
|
41
|
+
nx g @nx/angular:app --name=ng-app --directory=apps/ng-app --tags="scope:client,type:app" --e2eTestRunner=none --style=scss --no-interactive
|
|
42
|
+
|
|
43
|
+
echo "---------------------------------------------------------"
|
|
44
|
+
|
|
45
|
+
# Bước 5: Tạo Thư viện Chung (JS/TS)
|
|
46
|
+
echo "📚 Đang tạo thư viện chung 'data-types'..."
|
|
47
|
+
npm install --save-dev @nx/js
|
|
48
|
+
nx g @nx/js:library --name=data-types --directory=packages/shared/data-types --tags="scope:shared,type:lib" --no-interactive
|
|
49
|
+
|
|
50
|
+
echo "---------------------------------------------------------"
|
|
51
|
+
|
|
52
|
+
# Bước 6: Tạo Thư viện Data Access (Angular)
|
|
53
|
+
echo "📚 Đang tạo thư viện 'data-access' cho Angular..."
|
|
54
|
+
nx g @nx/angular:library --name=data-access --directory=packages/client/data-access --tags="scope:client,type:lib" --style=scss --no-interactive
|
|
55
|
+
|
|
56
|
+
echo "---------------------------------------------------------"
|
|
57
|
+
|
|
58
|
+
# Bước 7: TỰ ĐỘNG TẠO FILE PROXY.CONF.JSON (ĐÃ SỬA)
|
|
59
|
+
echo "🔗 Đang tạo file 'apps/ng-app/proxy.conf.json'..."
|
|
60
|
+
|
|
61
|
+
cat <<EOF > apps/ng-app/proxy.conf.json
|
|
62
|
+
{
|
|
63
|
+
"/api": {
|
|
64
|
+
"target": "http://localhost:3000",
|
|
65
|
+
"secure": false,
|
|
66
|
+
"logLevel": "debug"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
EOF
|
|
70
|
+
|
|
71
|
+
echo "✅ File 'proxy.conf.json' đã được tạo."
|
|
72
|
+
echo "---------------------------------------------------------"
|
|
73
|
+
echo "🎉 HOÀN TẤT (với 2 bước thủ công)!"
|
|
74
|
+
echo "---------------------------------------------------------"
|
|
75
|
+
echo ""
|
|
76
|
+
echo "‼️ YÊU CẦU HÀNH ĐỘNG THỦ CÔNG (2 BƯỚC) ‼️"
|
|
77
|
+
echo "Script đã tạo file 'proxy.conf.json', nhưng bạn cần kết nối nó với 'ng-app'."
|
|
78
|
+
echo ""
|
|
79
|
+
echo "👉 Mở file: ./$WORKSPACE_NAME/apps/ng-app/project.json"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "1. Thêm 'proxyConfig' vào target 'serve' (trong 'options'):"
|
|
82
|
+
echo '
|
|
83
|
+
"serve": {
|
|
84
|
+
"executor": "@nx/angular:dev-server",
|
|
85
|
+
"options": {
|
|
86
|
+
"proxyConfig": "apps/ng-app/proxy.conf.json" <-- THÊM DÒNG NÀY
|
|
87
|
+
},
|
|
88
|
+
'
|
|
89
|
+
echo ""
|
|
90
|
+
echo "2. Thêm 'dependsOn' vào target 'serve' (để tự động chạy API):"
|
|
91
|
+
echo '
|
|
92
|
+
"serve": {
|
|
93
|
+
...
|
|
94
|
+
"defaultConfiguration": "development",
|
|
95
|
+
"dependsOn": [ <-- THÊM KHỐI NÀY
|
|
96
|
+
{
|
|
97
|
+
"target": "serve",
|
|
98
|
+
"projects": "api"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
'
|
|
103
|
+
echo ""
|
|
104
|
+
echo "Sau khi hoàn tất 2 bước trên, bạn có thể chạy:"
|
|
105
|
+
echo "nx serve ng-app"
|
|
106
|
+
|
|
107
|
+
# ulimit -n 10240 && ./init-nx-monorepo.sh
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vg-coder-cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "🚀 CLI tool to analyze projects, concatenate source files, count tokens, and export HTML with syntax highlighting and
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "🚀 CLI tool to analyze projects, concatenate source files, count tokens, and export HTML with syntax highlighting. Now with modern NestJS API and Angular dashboard!",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"vg": "./bin/vg.js",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"test": "jest",
|
|
13
13
|
"test:watch": "jest --watch",
|
|
14
14
|
"dev": "nodemon src/index.js",
|
|
15
|
-
"push": "npm pack && npm publish"
|
|
15
|
+
"push": "npm pack && npm publish",
|
|
16
|
+
"build:vg": "cd vg && nx run-many --target=build --all --configuration=production",
|
|
17
|
+
"start:vg": "cd vg && ./start-dev.sh"
|
|
16
18
|
},
|
|
17
19
|
"keywords": [
|
|
18
20
|
"cli",
|
|
@@ -31,7 +33,12 @@
|
|
|
31
33
|
"vue",
|
|
32
34
|
"java",
|
|
33
35
|
"javascript",
|
|
34
|
-
"typescript"
|
|
36
|
+
"typescript",
|
|
37
|
+
"nestjs",
|
|
38
|
+
"nx-monorepo",
|
|
39
|
+
"modern-stack",
|
|
40
|
+
"api-server",
|
|
41
|
+
"dashboard"
|
|
35
42
|
],
|
|
36
43
|
"author": "VG Coder",
|
|
37
44
|
"license": "MIT",
|
package/src/index.js
CHANGED
|
@@ -66,6 +66,7 @@ class VGCoderCLI {
|
|
|
66
66
|
.alias('s')
|
|
67
67
|
.description('Khởi động API server')
|
|
68
68
|
.option('-p, --port <port>', 'Port cho server', '6868')
|
|
69
|
+
.option('--new', 'Khởi động NestJS/Angular stack (modern)')
|
|
69
70
|
.action(this.handleStart.bind(this));
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -372,6 +373,61 @@ class VGCoderCLI {
|
|
|
372
373
|
*/
|
|
373
374
|
async handleStart(options) {
|
|
374
375
|
try {
|
|
376
|
+
// Check if --new flag is set
|
|
377
|
+
if (options.new) {
|
|
378
|
+
console.log(chalk.blue('🚀 Starting NestJS/Angular stack...'));
|
|
379
|
+
console.log(chalk.yellow('This will start both API (port 3000) and Angular (port 4200)'));
|
|
380
|
+
console.log('');
|
|
381
|
+
|
|
382
|
+
// Check if vg directory exists
|
|
383
|
+
const vgPath = path.join(__dirname, '..', 'vg');
|
|
384
|
+
if (!await fs.pathExists(vgPath)) {
|
|
385
|
+
throw new Error('VG workspace not found. Make sure you have the complete package installed.');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Check if start-dev.sh exists
|
|
389
|
+
const startScript = path.join(vgPath, 'start-dev.sh');
|
|
390
|
+
if (!await fs.pathExists(startScript)) {
|
|
391
|
+
throw new Error('start-dev.sh not found in vg directory.');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Execute start-dev.sh
|
|
395
|
+
const { spawn } = require('child_process');
|
|
396
|
+
const child = spawn('bash', [startScript], {
|
|
397
|
+
cwd: vgPath,
|
|
398
|
+
stdio: 'inherit'
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
child.on('error', (error) => {
|
|
402
|
+
console.error(chalk.red('Failed to start:'), error.message);
|
|
403
|
+
process.exit(1);
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
child.on('exit', (code) => {
|
|
407
|
+
if (code !== 0) {
|
|
408
|
+
console.error(chalk.red(`Process exited with code ${code}`));
|
|
409
|
+
process.exit(code);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Handle graceful shutdown
|
|
414
|
+
const shutdown = () => {
|
|
415
|
+
console.log(chalk.yellow('\n\nShutting down...'));
|
|
416
|
+
child.kill('SIGTERM');
|
|
417
|
+
process.exit(0);
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
process.on('SIGINT', shutdown);
|
|
421
|
+
process.on('SIGTERM', shutdown);
|
|
422
|
+
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Legacy Express server
|
|
427
|
+
console.log(chalk.blue('🚀 Starting Express server (legacy)...'));
|
|
428
|
+
console.log(chalk.yellow('💡 Tip: Use --new flag to start the modern NestJS/Angular stack'));
|
|
429
|
+
console.log('');
|
|
430
|
+
|
|
375
431
|
const port = parseInt(options.port);
|
|
376
432
|
const server = new ApiServer(port);
|
|
377
433
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"type": "node",
|
|
6
|
+
"request": "launch",
|
|
7
|
+
"name": "Debug api with Nx",
|
|
8
|
+
"runtimeExecutable": "npx",
|
|
9
|
+
"runtimeArgs": ["nx", "serve", "api"],
|
|
10
|
+
"env": {
|
|
11
|
+
"NODE_OPTIONS": "--inspect=9229"
|
|
12
|
+
},
|
|
13
|
+
"console": "integratedTerminal",
|
|
14
|
+
"internalConsoleOptions": "neverOpen",
|
|
15
|
+
"skipFiles": ["<node_internals>/**"],
|
|
16
|
+
"sourceMaps": true,
|
|
17
|
+
"outFiles": [
|
|
18
|
+
"${workspaceFolder}/apps/api/dist/**/*.(m|c|)js",
|
|
19
|
+
"!**/node_modules/**"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
package/vg/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# VG Coder - NestJS/Angular Upgrade
|
|
2
|
+
|
|
3
|
+
## Quick Start
|
|
4
|
+
|
|
5
|
+
### Start Both Applications
|
|
6
|
+
```bash
|
|
7
|
+
cd vg
|
|
8
|
+
nx run-many --target=serve --projects=api,ng-app
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This will start:
|
|
12
|
+
- **API Backend** on `http://localhost:3000`
|
|
13
|
+
- **Angular Dashboard** on `http://localhost:4200`
|
|
14
|
+
|
|
15
|
+
### Start Individually
|
|
16
|
+
|
|
17
|
+
**Backend only:**
|
|
18
|
+
```bash
|
|
19
|
+
cd vg
|
|
20
|
+
nx serve api
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Frontend only:**
|
|
24
|
+
```bash
|
|
25
|
+
cd vg
|
|
26
|
+
nx serve ng-app
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Project Structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
vg/
|
|
33
|
+
├── apps/
|
|
34
|
+
│ ├── api/ # NestJS backend
|
|
35
|
+
│ └── ng-app/ # Angular frontend
|
|
36
|
+
└── packages/
|
|
37
|
+
└── core/ # Shared TypeScript library
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Available Endpoints
|
|
41
|
+
|
|
42
|
+
| Endpoint | Method | Description |
|
|
43
|
+
|----------|--------|-------------|
|
|
44
|
+
| `/api/analyze` | POST | Analyze project and return source code |
|
|
45
|
+
| `/api/execute` | POST | Execute bash scripts with validation |
|
|
46
|
+
| `/api/info` | GET | Get project information and statistics |
|
|
47
|
+
| `/api/clean` | DELETE | Clean output directories |
|
|
48
|
+
|
|
49
|
+
## Development
|
|
50
|
+
|
|
51
|
+
### Build All
|
|
52
|
+
```bash
|
|
53
|
+
nx run-many --target=build --all
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Build Specific Project
|
|
57
|
+
```bash
|
|
58
|
+
nx build core
|
|
59
|
+
nx build api
|
|
60
|
+
nx build ng-app
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Test
|
|
64
|
+
```bash
|
|
65
|
+
nx test core
|
|
66
|
+
nx test api
|
|
67
|
+
nx test ng-app
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Architecture
|
|
71
|
+
|
|
72
|
+
- **Core Library** (`@vg/core`): Shared business logic
|
|
73
|
+
- ProjectDetector
|
|
74
|
+
- FileScanner
|
|
75
|
+
- TokenManager
|
|
76
|
+
- BashExecutor
|
|
77
|
+
- IgnoreManager
|
|
78
|
+
|
|
79
|
+
- **API Backend**: NestJS REST API with controllers and services
|
|
80
|
+
- **Frontend**: Angular standalone components with reactive forms
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
- **Proxy**: Angular dev server proxies `/api` requests to `http://localhost:3000`
|
|
85
|
+
- **CORS**: NestJS allows requests from `http://localhost:4200`
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "api",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "apps/api/src",
|
|
5
|
+
"projectType": "application",
|
|
6
|
+
"targets": {
|
|
7
|
+
"build": {
|
|
8
|
+
"executor": "nx:run-commands",
|
|
9
|
+
"options": {
|
|
10
|
+
"command": "npx webpack-cli build",
|
|
11
|
+
"args": [
|
|
12
|
+
"--node-env=production"
|
|
13
|
+
],
|
|
14
|
+
"cwd": "apps/api"
|
|
15
|
+
},
|
|
16
|
+
"configurations": {
|
|
17
|
+
"development": {
|
|
18
|
+
"args": [
|
|
19
|
+
"--node-env=development"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"prune-lockfile": {
|
|
25
|
+
"dependsOn": [
|
|
26
|
+
"build"
|
|
27
|
+
],
|
|
28
|
+
"cache": true,
|
|
29
|
+
"executor": "@nx/js:prune-lockfile",
|
|
30
|
+
"outputs": [
|
|
31
|
+
"{workspaceRoot}/dist/apps/api/package.json",
|
|
32
|
+
"{workspaceRoot}/dist/apps/api/package-lock.json"
|
|
33
|
+
],
|
|
34
|
+
"options": {
|
|
35
|
+
"buildTarget": "build"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"copy-workspace-modules": {
|
|
39
|
+
"dependsOn": [
|
|
40
|
+
"build"
|
|
41
|
+
],
|
|
42
|
+
"cache": true,
|
|
43
|
+
"outputs": [
|
|
44
|
+
"{workspaceRoot}/dist/apps/api/workspace_modules"
|
|
45
|
+
],
|
|
46
|
+
"executor": "@nx/js:copy-workspace-modules",
|
|
47
|
+
"options": {
|
|
48
|
+
"buildTarget": "build"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"prune": {
|
|
52
|
+
"dependsOn": [
|
|
53
|
+
"prune-lockfile",
|
|
54
|
+
"copy-workspace-modules"
|
|
55
|
+
],
|
|
56
|
+
"executor": "nx:noop"
|
|
57
|
+
},
|
|
58
|
+
"serve": {
|
|
59
|
+
"continuous": true,
|
|
60
|
+
"executor": "@nx/js:node",
|
|
61
|
+
"defaultConfiguration": "development",
|
|
62
|
+
"dependsOn": [
|
|
63
|
+
"build"
|
|
64
|
+
],
|
|
65
|
+
"options": {
|
|
66
|
+
"buildTarget": "api:build",
|
|
67
|
+
"runBuildTargetDependencies": false
|
|
68
|
+
},
|
|
69
|
+
"configurations": {
|
|
70
|
+
"development": {
|
|
71
|
+
"buildTarget": "api:build:development"
|
|
72
|
+
},
|
|
73
|
+
"production": {
|
|
74
|
+
"buildTarget": "api:build:production"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"tags": [
|
|
80
|
+
"scope:server",
|
|
81
|
+
"type:app"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Controller, Post, Body, Res } from '@nestjs/common';
|
|
2
|
+
import { Response } from 'express';
|
|
3
|
+
import { AnalyzeService } from './analyze.service';
|
|
4
|
+
|
|
5
|
+
@Controller('analyze')
|
|
6
|
+
export class AnalyzeController {
|
|
7
|
+
constructor(private readonly analyzeService: AnalyzeService) { }
|
|
8
|
+
|
|
9
|
+
@Post()
|
|
10
|
+
async analyze(@Body() body: { path: string; options?: any }, @Res() res: Response) {
|
|
11
|
+
const content = await this.analyzeService.analyzeProject(body.path, body.options);
|
|
12
|
+
|
|
13
|
+
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
14
|
+
res.setHeader('Content-Disposition', 'attachment; filename="project.txt"');
|
|
15
|
+
res.send(content);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Injectable, BadRequestException, NotFoundException, InternalServerErrorException, Logger } from '@nestjs/common';
|
|
2
|
+
import { ProjectDetector, FileScanner } from '@vg/core';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as fs from 'fs-extra';
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class AnalyzeService {
|
|
8
|
+
private readonly logger = new Logger(AnalyzeService.name);
|
|
9
|
+
|
|
10
|
+
async analyzeProject(projectPath: string, options: any = {}) {
|
|
11
|
+
try {
|
|
12
|
+
if (!projectPath) {
|
|
13
|
+
throw new BadRequestException('Missing required field: path');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const resolvedPath = path.resolve(projectPath);
|
|
17
|
+
|
|
18
|
+
// Validate project path
|
|
19
|
+
if (!await fs.pathExists(resolvedPath)) {
|
|
20
|
+
throw new NotFoundException(`Project path does not exist: ${projectPath}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.logger.log(`Analyzing project: ${resolvedPath}`);
|
|
24
|
+
|
|
25
|
+
// Detect project type (optional, but good for logging)
|
|
26
|
+
const detector = new ProjectDetector(resolvedPath);
|
|
27
|
+
await detector.detectAll();
|
|
28
|
+
|
|
29
|
+
// Scan files
|
|
30
|
+
const scannerOptions = {
|
|
31
|
+
extensions: options.extensions ? options.extensions.split(',').map((ext: string) => ext.trim()) : undefined,
|
|
32
|
+
includeHidden: options.includeHidden || false
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const scanner = new FileScanner(resolvedPath, scannerOptions);
|
|
36
|
+
const scanResult = await scanner.scanProject();
|
|
37
|
+
|
|
38
|
+
// Create AI-friendly content
|
|
39
|
+
const aiContent = await scanner.createCombinedContentForAI(scanResult.files, {
|
|
40
|
+
includeStats: true,
|
|
41
|
+
includeTree: true,
|
|
42
|
+
preserveLineNumbers: true
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.logger.log(`✓ Analysis completed: ${scanResult.files.length} files`);
|
|
46
|
+
|
|
47
|
+
return aiContent;
|
|
48
|
+
|
|
49
|
+
} catch (error: any) {
|
|
50
|
+
this.logger.error('Error during analysis:', error);
|
|
51
|
+
if (error instanceof BadRequestException || error instanceof NotFoundException) {
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
throw new InternalServerErrorException(error.message || 'Analysis failed');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Controller, Get } from '@nestjs/common';
|
|
2
|
+
import { AppService } from './app.service';
|
|
3
|
+
|
|
4
|
+
@Controller()
|
|
5
|
+
export class AppController {
|
|
6
|
+
constructor(private readonly appService: AppService) {}
|
|
7
|
+
|
|
8
|
+
@Get()
|
|
9
|
+
getData() {
|
|
10
|
+
return this.appService.getData();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { AppController } from './app.controller';
|
|
4
|
+
import { AppService } from './app.service';
|
|
5
|
+
import { AnalyzeController } from './analyze.controller';
|
|
6
|
+
import { AnalyzeService } from './analyze.service';
|
|
7
|
+
import { ExecuteController } from './execute.controller';
|
|
8
|
+
import { ExecuteService } from './execute.service';
|
|
9
|
+
import { InfoController } from './info.controller';
|
|
10
|
+
import { InfoService } from './info.service';
|
|
11
|
+
import { CleanController } from './clean.controller';
|
|
12
|
+
|
|
13
|
+
@Module({
|
|
14
|
+
imports: [],
|
|
15
|
+
controllers: [
|
|
16
|
+
AppController,
|
|
17
|
+
AnalyzeController,
|
|
18
|
+
ExecuteController,
|
|
19
|
+
InfoController,
|
|
20
|
+
CleanController
|
|
21
|
+
],
|
|
22
|
+
providers: [
|
|
23
|
+
AppService,
|
|
24
|
+
AnalyzeService,
|
|
25
|
+
ExecuteService,
|
|
26
|
+
InfoService
|
|
27
|
+
],
|
|
28
|
+
})
|
|
29
|
+
export class AppModule { }
|