vg-coder-cli 2.0.9 → 2.0.11

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 (73) hide show
  1. package/DEVELOPMENT.md +95 -0
  2. package/README.md +19 -0
  3. package/SYSTEM_PROMPT.md +157 -0
  4. package/coverage/base.css +224 -0
  5. package/coverage/block-navigation.js +87 -0
  6. package/coverage/favicon.png +0 -0
  7. package/coverage/index.html +206 -0
  8. package/coverage/lcov-report/base.css +224 -0
  9. package/coverage/lcov-report/block-navigation.js +87 -0
  10. package/coverage/lcov-report/favicon.png +0 -0
  11. package/coverage/lcov-report/index.html +206 -0
  12. package/coverage/lcov-report/prettify.css +1 -0
  13. package/coverage/lcov-report/prettify.js +2 -0
  14. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  15. package/coverage/lcov-report/sorter.js +210 -0
  16. package/coverage/lcov-report/src/detectors/index.html +116 -0
  17. package/coverage/lcov-report/src/detectors/project-detector.js.html +1084 -0
  18. package/coverage/lcov-report/src/exporter/html-exporter.js.html +2839 -0
  19. package/coverage/lcov-report/src/exporter/index.html +116 -0
  20. package/coverage/lcov-report/src/ignore/ignore-manager.js.html +979 -0
  21. package/coverage/lcov-report/src/ignore/index.html +116 -0
  22. package/coverage/lcov-report/src/index.html +116 -0
  23. package/coverage/lcov-report/src/index.js.html +928 -0
  24. package/coverage/lcov-report/src/scanner/file-scanner.js.html +1903 -0
  25. package/coverage/lcov-report/src/scanner/index.html +116 -0
  26. package/coverage/lcov-report/src/tokenizer/index.html +116 -0
  27. package/coverage/lcov-report/src/tokenizer/token-manager.js.html +1252 -0
  28. package/coverage/lcov-report/src/utils/helpers.js.html +469 -0
  29. package/coverage/lcov-report/src/utils/index.html +116 -0
  30. package/coverage/lcov.info +1396 -0
  31. package/coverage/prettify.css +1 -0
  32. package/coverage/prettify.js +2 -0
  33. package/coverage/sort-arrow-sprite.png +0 -0
  34. package/coverage/sorter.js +210 -0
  35. package/coverage/src/detectors/index.html +116 -0
  36. package/coverage/src/detectors/project-detector.js.html +1084 -0
  37. package/coverage/src/exporter/html-exporter.js.html +2839 -0
  38. package/coverage/src/exporter/index.html +116 -0
  39. package/coverage/src/ignore/ignore-manager.js.html +979 -0
  40. package/coverage/src/ignore/index.html +116 -0
  41. package/coverage/src/index.html +116 -0
  42. package/coverage/src/index.js.html +928 -0
  43. package/coverage/src/scanner/file-scanner.js.html +1903 -0
  44. package/coverage/src/scanner/index.html +116 -0
  45. package/coverage/src/tokenizer/index.html +116 -0
  46. package/coverage/src/tokenizer/token-manager.js.html +1252 -0
  47. package/coverage/src/utils/helpers.js.html +469 -0
  48. package/coverage/src/utils/index.html +116 -0
  49. package/jest.config.js +16 -0
  50. package/package.json +5 -3
  51. package/scripts/build.js +40 -0
  52. package/src/server/api-server.js +15 -0
  53. package/src/server/views/css/iframe.css +84 -0
  54. package/src/server/views/css/structure.css +63 -37
  55. package/src/server/views/dashboard.css +127 -310
  56. package/src/server/views/dashboard.html +165 -119
  57. package/src/server/views/js/features/iframe-manager.js +56 -0
  58. package/src/server/views/js/main.js +64 -0
  59. package/src/server/views/vg-coder/assets/icon128.png +0 -0
  60. package/src/server/views/vg-coder/assets/icon16.png +0 -0
  61. package/src/server/views/vg-coder/assets/icon48.png +0 -0
  62. package/src/server/views/vg-coder/background.js +2 -0
  63. package/src/server/views/vg-coder/background.js.LICENSE.txt +118 -0
  64. package/src/server/views/vg-coder/controller.js +1 -0
  65. package/src/server/views/vg-coder/manifest.json +58 -0
  66. package/src/server/views/vg-coder/options.css +164 -0
  67. package/src/server/views/vg-coder/options.html +48 -0
  68. package/src/server/views/vg-coder/options.js +1 -0
  69. package/src/server/views/vg-coder/rules.json +23 -0
  70. package/vg-coder-cli-2.0.11.tgz +0 -0
  71. package/vg-coder.zip +0 -0
  72. package/vg-coder-cli-2.0.8.tgz +0 -0
  73. package/vg-coder-cli-2.0.9.tgz +0 -0
@@ -5,14 +5,12 @@
5
5
  <meta charset="UTF-8">
6
6
  <meta name="viewport"
7
7
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
8
- <meta name="apple-mobile-web-app-capable" content="yes">
9
- <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
10
- <title>VG Coder API Dashboard</title>
8
+ <title>VG Coder - Split View</title>
11
9
  <link rel="stylesheet" href="/dashboard.css">
12
10
  <link rel="stylesheet" href="/css/structure.css">
11
+ <link rel="stylesheet" href="/css/iframe.css">
13
12
  <script>
14
- // Pre-load theme to prevent flash
15
- (function() {
13
+ (function () {
16
14
  const savedTheme = localStorage.getItem('theme') || 'light';
17
15
  document.documentElement.setAttribute('data-theme', savedTheme);
18
16
  })();
@@ -20,138 +18,186 @@
20
18
  </head>
21
19
 
22
20
  <body>
23
- <div class="container">
24
- <div class="header">
25
- <div class="header-content">
26
- <span class="status" id="status">● Server Starting...</span>
27
- <div style="height: 10px;"></div>
28
- <h1>VG Coder</h1>
29
- <p>API Dashboard & Automation</p>
30
- </div>
31
- <button class="theme-toggle" id="theme-toggle" title="Toggle Dark Mode">
32
- <span id="theme-icon">🌙</span>
33
- </button>
34
- </div>
35
-
36
- <!-- System Prompt Section -->
37
- <div class="system-prompt-card">
38
- <div class="system-prompt-header" onclick="toggleSystemPrompt()">
39
- <div class="header-title-group">
40
- <button class="btn-icon-head" onclick="copySystemPromptFromHeader(event)" title="Copy System Prompt">
41
- 📋
21
+ <div class="split-layout">
22
+ <!-- CỘT TRÁI: Giao diện VG Coder -->
23
+ <div class="left-panel">
24
+ <div class="container">
25
+ <div class="header">
26
+ <div class="header-content">
27
+ <span class="status" id="status">● Server Starting...</span>
28
+ <div style="height: 5px;"></div>
29
+ </div>
30
+ <button class="theme-toggle" id="theme-toggle" title="Toggle Dark Mode">
31
+ <span id="theme-icon">🌙</span>
42
32
  </button>
43
- <h2>System Prompt</h2>
44
33
  </div>
45
- <span class="toggle-icon" id="toggle-icon">▼</span>
46
- </div>
47
- <div class="system-prompt-content" id="system-prompt-content">
48
- <div class="prompt-text" id="prompt-text"></div>
49
- <button class="btn btn-copy" onclick="copySystemPrompt(event)">
50
- <span id="copy-icon">📋</span>
51
- <span id="copy-text">Copy System Prompt</span>
52
- </button>
53
- </div>
54
- </div>
55
34
 
56
- <div class="endpoints">
57
- <!-- Analyze -->
58
- <div class="endpoint-card">
59
- <div class="endpoint-header">
60
- <!-- Left side: Method + Path -->
61
- <div class="endpoint-title-group">
62
- <span class="method post">POST</span>
63
- <span class="endpoint-path">/api/analyze</span>
35
+ <!-- System Prompt Section -->
36
+ <div class="system-prompt-card">
37
+ <div class="system-prompt-header" onclick="toggleSystemPrompt()">
38
+ <div class="header-title-group">
39
+ <button class="btn-icon-head" onclick="copySystemPromptFromHeader(event)"
40
+ title="Copy System Prompt">
41
+ 📋
42
+ </button>
43
+ <h2>System Prompt</h2>
44
+ </div>
45
+ <span class="toggle-icon" id="toggle-icon">▼</span>
46
+ </div>
47
+ <div class="system-prompt-content" id="system-prompt-content">
48
+ <div class="prompt-text" id="prompt-text"></div>
49
+ <button class="btn btn-copy" onclick="copySystemPrompt(event)">
50
+ <span id="copy-icon">📋</span>
51
+ <span id="copy-text">Copy System Prompt</span>
52
+ </button>
64
53
  </div>
65
- <!-- Right side: Download Icon -->
66
- <button class="btn-icon-head" onclick="testAnalyze(event)" title="Download Project Source">
67
- 📥
68
- </button>
69
- </div>
70
- <p class="endpoint-desc">Phân tích dự án và lấy toàn bộ source code.</p>
71
- <div class="form-group">
72
- <label>Path</label>
73
- <input type="text" id="analyze-path" value="." placeholder="Project path (e.g. .)">
74
- </div>
75
- <div class="btn-group">
76
- <!-- Big Download button removed as it's now in the header -->
77
- <button class="btn btn-copy" onclick="copyAnalyzeResult(event)">
78
- <span id="analyze-copy-icon">📋</span>
79
- <span id="analyze-copy-text">Copy Text</span>
80
- </button>
81
54
  </div>
82
- <div class="response" id="analyze-response"></div>
83
- </div>
84
55
 
85
- <!-- Execute Bash -->
86
- <div class="endpoint-card">
87
- <div class="endpoint-header">
88
- <div class="endpoint-title-group">
89
- <span class="method post">POST</span>
90
- <span class="endpoint-path">/api/execute</span>
56
+ <!-- Extension Installation Guide -->
57
+ <div class="system-prompt-card" id="extension-card">
58
+ <div class="system-prompt-header" onclick="toggleExtensionGuide()">
59
+ <div class="header-title-group">
60
+ <span style="font-size: 16px;">🧩</span>
61
+ <h2>Cài đặt Chrome Extension</h2>
62
+ </div>
63
+ <span class="toggle-icon" id="ext-toggle-icon">▼</span>
64
+ </div>
65
+ <div class="system-prompt-content" id="extension-content">
66
+ <div class="extension-steps">
67
+ <ol>
68
+ <li style="margin-bottom: 8px;">
69
+ Copy link này và dán vào tab mới:
70
+ <div class="form-group" style="margin-top: 5px; margin-bottom: 0;">
71
+ <div style="display: flex; gap: 5px;">
72
+ <input type="text" id="chrome-url-input" readonly
73
+ value="chrome://extensions" onclick="this.select()"
74
+ style="font-family: monospace;">
75
+ <button class="btn btn-copy" style="flex: 0 0 40px; padding: 0;"
76
+ onclick="copyChromeUrl(event)" title="Copy URL">
77
+ <span>📋</span>
78
+ </button>
79
+ </div>
80
+ </div>
81
+ </li>
82
+ <li>Bật <b>Developer mode</b> (Góc phải trên cùng)</li>
83
+ <li>Chọn <b>Load unpacked</b></li>
84
+ <li>Dán đường dẫn bên dưới vào:</li>
85
+ </ol>
86
+ </div>
87
+ <div class="form-group">
88
+ <input type="text" id="extension-path-input" readonly value="Loading path..."
89
+ onclick="this.select()">
90
+ </div>
91
+ <button class="btn btn-copy" onclick="copyExtensionPath(event)">
92
+ <span id="ext-copy-icon">📋</span>
93
+ <span id="ext-copy-text">Copy Path</span>
94
+ </button>
91
95
  </div>
92
- <!-- Could add an execute icon here later if needed -->
93
- </div>
94
- <p class="endpoint-desc">Thực thi bash script với syntax validation.</p>
95
- <div class="form-group">
96
- <label>Bash Script</label>
97
- <textarea id="execute-bash"
98
- placeholder="mkdir -p src/test&#10;echo 'Hello' > src/test/hello.txt"></textarea>
99
- </div>
100
- <div class="btn-group">
101
- <button class="btn" onclick="testExecute(event)">
102
- <span>▶️</span>
103
- <span>Run Script</span>
104
- </button>
105
- <button class="btn" onclick="executeFromClipboard(event)">
106
- <span>📋</span>
107
- <span>Paste & Run</span>
108
- </button>
109
96
  </div>
110
- <div class="response" id="execute-response"></div>
111
- </div>
112
97
 
113
- <!-- Structure & Tokens (NEW) -->
114
- <div class="endpoint-card">
115
- <div class="endpoint-header">
116
- <div class="endpoint-title-group">
117
- <span class="method get" style="background: var(--ios-blue); color: white;">GET</span>
118
- <span class="endpoint-path">/api/structure</span>
98
+ <div class="endpoints">
99
+ <!-- Execute Bash -->
100
+ <div class="endpoint-card">
101
+ <div class="endpoint-header">
102
+ <div class="endpoint-title-group">
103
+ <span class="method post">POST</span>
104
+ <span class="endpoint-path">/execute</span>
105
+ </div>
106
+ </div>
107
+ <div class="form-group">
108
+ <textarea id="execute-bash"
109
+ placeholder="mkdir -p src/test&#10;echo 'Hello' > src/test/hello.txt"></textarea>
110
+ </div>
111
+ <div class="btn-group">
112
+ <button class="btn" onclick="testExecute(event)">
113
+ <span>▶️</span> Run
114
+ </button>
115
+ <button class="btn" onclick="executeFromClipboard(event)">
116
+ <span>📋</span> Paste & Run
117
+ </button>
118
+ </div>
119
+ <div class="response" id="execute-response"></div>
120
+ </div>
121
+
122
+ <!-- Structure -->
123
+ <div class="endpoint-card">
124
+ <div class="endpoint-header">
125
+ <div class="endpoint-title-group">
126
+ <span class="method get" style="background: var(--ios-blue); color: white;">GET</span>
127
+ <span class="endpoint-path">/structure</span>
128
+ </div>
129
+ <button class="btn-icon-head" onclick="copySelectedStructure(event)" title="Copy Selected">
130
+ 📋
131
+ </button>
132
+ </div>
133
+ <div class="form-group">
134
+ <input type="text" id="structure-path" value="." placeholder="Project path">
135
+ </div>
136
+ <div class="btn-group">
137
+ <button class="btn" onclick="testStructure(event)">
138
+ <span>🌳</span> View
139
+ </button>
140
+ </div>
141
+ <div class="tree-container" id="structure-tree" style="display: none;">
142
+ <div class="tree-header">
143
+ <span>Tree</span>
144
+ <span class="tree-total-tokens" id="total-tokens-badge">0 tokens</span>
145
+ </div>
146
+ <div class="tree-content" id="tree-content"></div>
147
+ </div>
148
+ <div class="response" id="structure-response" style="display: none;"></div>
149
+ </div>
150
+
151
+ <!-- Analyze -->
152
+ <div class="endpoint-card">
153
+ <div class="endpoint-header">
154
+ <div class="endpoint-title-group">
155
+ <span class="method post">POST</span>
156
+ <span class="endpoint-path">/analyze</span>
157
+ </div>
158
+ <button class="btn-icon-head" onclick="testAnalyze(event)" title="Download Project Source">
159
+ 📥
160
+ </button>
161
+ </div>
162
+ <div class="form-group">
163
+ <input type="text" id="analyze-path" value="." placeholder="Project path (e.g. .)">
164
+ </div>
165
+ <div class="btn-group">
166
+ <button class="btn btn-copy" onclick="copyAnalyzeResult(event)">
167
+ <span id="analyze-copy-icon">📋</span>
168
+ <span id="analyze-copy-text">Copy Text</span>
169
+ </button>
170
+ </div>
171
+ <div class="response" id="analyze-response"></div>
119
172
  </div>
120
- <!-- Button Copy Selected -->
121
- <button class="btn-icon-head" onclick="copySelectedStructure(event)" title="Copy Selected Tree">
122
- 📋
123
- </button>
124
- </div>
125
- <p class="endpoint-desc">Xem cây thư mục và phân tích số lượng Token.</p>
126
- <div class="form-group">
127
- <label>Path</label>
128
- <input type="text" id="structure-path" value="." placeholder="Project path">
129
173
  </div>
130
- <div class="btn-group">
131
- <button class="btn" onclick="testStructure(event)">
132
- <span>🌳</span>
133
- <span>View Structure</span>
134
- </button>
135
- <button class="btn btn-copy" onclick="copySelectedStructure(event)">
136
- <span id="copy-structure-icon">📋</span>
137
- <span id="copy-structure-text">Copy Selected</span>
138
- </button>
174
+ <div style="height: 50px;"></div> <!-- Spacer for scrolling -->
175
+ </div>
176
+ </div>
177
+
178
+ <!-- CỘT PHẢI: AI Iframe with Selector -->
179
+ <div class="right-panel">
180
+ <div class="ai-header">
181
+ <div class="ai-select-group">
182
+ <span style="font-size: 16px;">🤖</span>
183
+ <select id="ai-provider-select" class="ai-select">
184
+ <!-- Options filled by JS -->
185
+ </select>
139
186
  </div>
140
- <!-- Tree Container -->
141
- <div class="tree-container" id="structure-tree" style="display: none;">
142
- <div class="tree-header">
143
- <span>Project Tree</span>
144
- <span class="tree-total-tokens" id="total-tokens-badge">0 tokens</span>
145
- </div>
146
- <div class="tree-content" id="tree-content"></div>
187
+ <a id="ai-external-link" href="#" target="_blank" class="btn-icon-head" title="Open in new tab">↗</a>
188
+ </div>
189
+
190
+ <div class="ai-iframe-container">
191
+ <div class="iframe-placeholder">
192
+ <p>⚠️ Nếu trang trắng, hãy cài Extension <b>"Ignore X-Frame-Options"</b></p>
193
+ <a id="ai-placeholder-link" href="#" target="_blank" class="link-fallback">Mở tab mới ↗</a>
147
194
  </div>
148
- <div class="response" id="structure-response" style="display: none;"></div>
195
+ <iframe id="ai-iframe" src="" title="AI Integration"></iframe>
149
196
  </div>
150
197
  </div>
151
198
  </div>
152
199
 
153
200
  <div class="toast" id="toast"></div>
154
-
155
201
  <script type="module" src="/js/main.js"></script>
156
202
  </body>
157
203
 
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Quản lý tính năng Iframe AI Provider
3
+ */
4
+
5
+ // Danh sách các AI Providers
6
+ const AI_PROVIDERS = [
7
+ { id: 'chatgpt', name: 'ChatGPT', url: 'https://chat.openai.com' },
8
+ { id: 'kimi', name: 'Kimi AI', url: 'https://www.kimi.com' },
9
+ { id: 'deepseek', name: 'DeepSeek', url: 'https://chat.deepseek.com' },
10
+ { id: 'gemini', name: 'Google Gemini', url: 'https://gemini.google.com/app' },
11
+ { id: 'aistudio', name: 'Google AI Studio', url: 'https://aistudio.google.com/prompts/new_chat' }
12
+ ];
13
+
14
+ export function initIframeManager() {
15
+ const select = document.getElementById('ai-provider-select');
16
+ const iframe = document.getElementById('ai-iframe');
17
+ const externalLink = document.getElementById('ai-external-link');
18
+ const placeholderLink = document.getElementById('ai-placeholder-link');
19
+
20
+ if (!select || !iframe) return;
21
+
22
+ // 1. Populate options
23
+ AI_PROVIDERS.forEach(provider => {
24
+ const option = document.createElement('option');
25
+ option.value = provider.id;
26
+ option.textContent = provider.name;
27
+ select.appendChild(option);
28
+ });
29
+
30
+ // 2. Load saved selection or default
31
+ const savedProviderId = localStorage.getItem('ai_provider') || 'chatgpt';
32
+
33
+ // Validate if saved provider still exists
34
+ const isValid = AI_PROVIDERS.some(p => p.id === savedProviderId);
35
+ select.value = isValid ? savedProviderId : AI_PROVIDERS[0].id;
36
+
37
+ // 3. Function to update UI
38
+ const updateProvider = (providerId) => {
39
+ const provider = AI_PROVIDERS.find(p => p.id === providerId) || AI_PROVIDERS[0];
40
+
41
+ iframe.src = provider.url;
42
+ externalLink.href = provider.url;
43
+ placeholderLink.href = provider.url;
44
+ placeholderLink.textContent = `Mở ${provider.name} tab mới ↗`;
45
+
46
+ localStorage.setItem('ai_provider', providerId);
47
+ };
48
+
49
+ // 4. Initial update
50
+ updateProvider(select.value);
51
+
52
+ // 5. Event listener
53
+ select.addEventListener('change', (e) => {
54
+ updateProvider(e.target.value);
55
+ });
56
+ }
@@ -2,6 +2,8 @@
2
2
  import { SYSTEM_PROMPT } from './config.js';
3
3
  import { checkHealth } from './api.js';
4
4
  import './handlers.js'; // Import to register global functions
5
+ import { showToast, showCopiedState } from './utils.js';
6
+ import { initIframeManager } from './features/iframe-manager.js';
5
7
 
6
8
  /**
7
9
  * Initialize application on DOM ready
@@ -15,6 +17,12 @@ document.addEventListener('DOMContentLoaded', async () => {
15
17
 
16
18
  // Initialize Theme
17
19
  initTheme();
20
+
21
+ // Load Extension Path
22
+ loadExtensionPath();
23
+
24
+ // Initialize Iframe Manager (New Feature)
25
+ initIframeManager();
18
26
  });
19
27
 
20
28
  /**
@@ -70,3 +78,59 @@ function updateThemeIcon(theme) {
70
78
  themeIcon.textContent = '🌙';
71
79
  }
72
80
  }
81
+
82
+ // Extension Helpers
83
+ async function loadExtensionPath() {
84
+ try {
85
+ const res = await fetch('/api/extension-path');
86
+ const data = await res.json();
87
+ const input = document.getElementById('extension-path-input');
88
+
89
+ if (data.exists) {
90
+ input.value = data.path;
91
+ } else {
92
+ input.value = "Error: Extension folder not found. Run 'npm run build' first.";
93
+ input.style.color = "var(--ios-red)";
94
+ }
95
+ } catch (err) {
96
+ console.error('Failed to load extension path', err);
97
+ }
98
+ }
99
+
100
+ // Expose extension handlers to window for onclick events
101
+ window.toggleExtensionGuide = function() {
102
+ const content = document.getElementById('extension-content');
103
+ const icon = document.getElementById('ext-toggle-icon');
104
+ content.classList.toggle('open');
105
+ icon.classList.toggle('open');
106
+ }
107
+
108
+ window.copyExtensionPath = function(event) {
109
+ const input = document.getElementById('extension-path-input');
110
+ const btn = event.currentTarget;
111
+ const icon = document.getElementById('ext-copy-icon');
112
+ const text = document.getElementById('ext-copy-text');
113
+
114
+ navigator.clipboard.writeText(input.value).then(() => {
115
+ showCopiedState(btn, icon, text, '📋', 'Copy Path');
116
+ showToast('Đã copy đường dẫn extension', 'success');
117
+ }).catch(err => {
118
+ showToast('Lỗi copy: ' + err.message, 'error');
119
+ });
120
+ }
121
+
122
+ window.copyChromeUrl = function(event) {
123
+ const input = document.getElementById('chrome-url-input');
124
+ const btn = event.currentTarget;
125
+ const originalText = btn.innerHTML;
126
+
127
+ navigator.clipboard.writeText(input.value).then(() => {
128
+ btn.innerHTML = '✓';
129
+ showToast('Đã copy URL', 'success');
130
+ setTimeout(() => {
131
+ btn.innerHTML = originalText;
132
+ }, 1500);
133
+ }).catch(err => {
134
+ showToast('Lỗi copy: ' + err.message, 'error');
135
+ });
136
+ }