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
@@ -1,14 +1,16 @@
1
1
  // Event Handlers & Business Logic
2
2
  import { SYSTEM_PROMPT } from './config.js';
3
- import { analyzeProject, executeScript, copyAsFile, copyToClipboard, readFromClipboard } from './api.js';
3
+ import { analyzeProject, executeScript, copyToClipboard, readFromClipboard } from './api.js';
4
4
  import { showToast, showLoading, resetButton, showResponse, showCopiedState } from './utils.js';
5
+ // Import dedicated feature handlers
6
+ import { handleStructureView, handleToggleFolder, handleCheckboxChange, handleCopySelected } from './features/structure.js';
5
7
 
6
- // State management
7
8
  let lastAnalyzeResult = null;
8
9
 
9
- /**
10
- * Toggle system prompt section
11
- */
10
+ // ==========================================
11
+ // SYSTEM PROMPT HANDLERS
12
+ // ==========================================
13
+
12
14
  export function toggleSystemPrompt() {
13
15
  const content = document.getElementById('system-prompt-content');
14
16
  const icon = document.getElementById('toggle-icon');
@@ -16,32 +18,20 @@ export function toggleSystemPrompt() {
16
18
  icon.classList.toggle('open');
17
19
  }
18
20
 
19
- /**
20
- * Copy system prompt from the Header Button
21
- * Stops propagation so the accordion doesn't toggle
22
- */
23
21
  export function copySystemPromptFromHeader(event) {
24
- event.stopPropagation(); // Stop accordion from toggling
25
-
26
- // Animate button
22
+ event.stopPropagation();
27
23
  const btn = event.currentTarget;
28
24
  btn.textContent = '✓';
29
-
30
25
  navigator.clipboard.writeText(SYSTEM_PROMPT).then(() => {
31
26
  showToast('Đã copy System Prompt', 'success');
32
- setTimeout(() => {
33
- btn.textContent = '📋';
34
- }, 2000);
27
+ setTimeout(() => btn.textContent = '📋', 2000);
35
28
  }).catch(err => {
36
29
  showToast('Lỗi copy: ' + err.message, 'error');
37
30
  btn.textContent = '📋';
38
31
  });
39
32
  }
40
33
 
41
- /**
42
- * Copy system prompt to clipboard (Main content button)
43
- */
44
- export function copySystemPrompt() {
34
+ export function copySystemPrompt(event) {
45
35
  const copyBtn = event.target.closest('.btn-copy');
46
36
  const copyIcon = document.getElementById('copy-icon');
47
37
  const copyText = document.getElementById('copy-text');
@@ -49,16 +39,14 @@ export function copySystemPrompt() {
49
39
  navigator.clipboard.writeText(SYSTEM_PROMPT).then(() => {
50
40
  showCopiedState(copyBtn, copyIcon, copyText, '📋', 'Copy System Prompt');
51
41
  showToast('Đã copy System Prompt', 'success');
52
- }).catch(err => {
53
- showToast('Lỗi copy: ' + err.message, 'error');
54
- });
42
+ }).catch(err => showToast('Lỗi copy: ' + err.message, 'error'));
55
43
  }
56
44
 
57
- /**
58
- * Handle analyze button click
59
- */
60
- export async function testAnalyze() {
61
- // Support both the big button .btn and the header icon .btn-icon-head
45
+ // ==========================================
46
+ // ANALYZE HANDLERS
47
+ // ==========================================
48
+
49
+ export async function testAnalyze(event) {
62
50
  const btn = event.target.closest('.btn') || event.target.closest('.btn-icon-head');
63
51
  const path = document.getElementById('analyze-path').value;
64
52
 
@@ -67,7 +55,6 @@ export async function testAnalyze() {
67
55
  const text = await analyzeProject(path);
68
56
  lastAnalyzeResult = text;
69
57
 
70
- // Download file
71
58
  const blob = new Blob([text], { type: 'text/plain' });
72
59
  const url = window.URL.createObjectURL(blob);
73
60
  const a = document.createElement('a');
@@ -89,19 +76,14 @@ export async function testAnalyze() {
89
76
  resetButton(btn);
90
77
  }
91
78
 
92
- /**
93
- * Copy analyze result as text
94
- */
95
- export async function copyAnalyzeResult() {
79
+ export async function copyAnalyzeResult(event) {
96
80
  const copyBtn = event.target.closest('.btn-copy');
97
81
  const copyIcon = document.getElementById('analyze-copy-icon');
98
82
  const copyText = document.getElementById('analyze-copy-text');
99
83
 
100
84
  if (!lastAnalyzeResult) {
101
- // Fetch if not already analyzed
102
85
  const path = document.getElementById('analyze-path').value;
103
86
  showLoading(copyBtn, copyBtn.innerHTML);
104
-
105
87
  try {
106
88
  lastAnalyzeResult = await analyzeProject(path);
107
89
  } catch (err) {
@@ -112,7 +94,6 @@ export async function copyAnalyzeResult() {
112
94
  resetButton(copyBtn);
113
95
  }
114
96
 
115
- // Copy to clipboard
116
97
  try {
117
98
  await copyToClipboard(lastAnalyzeResult);
118
99
  showCopiedState(copyBtn, copyIcon, copyText, '📋', 'Copy Text');
@@ -122,10 +103,11 @@ export async function copyAnalyzeResult() {
122
103
  }
123
104
  }
124
105
 
125
- /**
126
- * Handle execute button click
127
- */
128
- export async function testExecute() {
106
+ // ==========================================
107
+ // EXECUTE HANDLERS
108
+ // ==========================================
109
+
110
+ export async function testExecute(event) {
129
111
  const btn = event.target.closest('.btn');
130
112
  const bashInput = document.getElementById('execute-bash');
131
113
  const bash = bashInput.value;
@@ -139,14 +121,8 @@ export async function testExecute() {
139
121
  try {
140
122
  const data = await executeScript(bash);
141
123
  showResponse('execute-response', data, !data.success);
142
-
143
- if (data.success) {
144
- showToast('Thực thi thành công', 'success');
145
- // Clear input on success
146
- bashInput.value = '';
147
- } else {
148
- showToast('Thực thi thất bại', 'error');
149
- }
124
+ data.success ? showToast('Thực thi thành công', 'success') : showToast('Thực thi thất bại', 'error');
125
+ if (data.success) bashInput.value = '';
150
126
  } catch (err) {
151
127
  showResponse('execute-response', { error: err.message }, true);
152
128
  showToast('Lỗi: ' + err.message, 'error');
@@ -154,44 +130,27 @@ export async function testExecute() {
154
130
  resetButton(btn);
155
131
  }
156
132
 
157
- /**
158
- * Execute script from clipboard
159
- */
160
- export async function executeFromClipboard() {
133
+ export async function executeFromClipboard(event) {
161
134
  const btn = event.target.closest('.btn');
162
135
  const bashInput = document.getElementById('execute-bash');
163
136
 
164
137
  showLoading(btn, btn.innerHTML);
165
-
166
138
  try {
167
139
  const clipboardText = await readFromClipboard();
168
-
169
140
  if (!clipboardText || !clipboardText.trim()) {
170
141
  showToast('Clipboard trống!', 'error');
171
- showResponse('execute-response', {
172
- error: 'Clipboard is empty',
173
- message: 'Please copy a bash script to clipboard first'
174
- }, true);
175
142
  resetButton(btn);
176
143
  return;
177
144
  }
178
-
179
- // Show what we are running
180
145
  bashInput.value = clipboardText;
181
-
182
146
  const data = await executeScript(clipboardText);
183
147
  showResponse('execute-response', data, !data.success);
184
-
148
+
185
149
  if (data.success) {
186
- showToast('Thực thi từ clipboard OK', 'success');
187
- // Clear input on success
150
+ showToast('Thực thi OK', 'success');
188
151
  bashInput.value = '';
189
152
  } else {
190
- if (data.syntaxError) {
191
- showToast('Lỗi syntax script', 'error');
192
- } else {
193
- showToast('Thực thi thất bại', 'error');
194
- }
153
+ data.syntaxError ? showToast('Lỗi syntax script', 'error') : showToast('Thực thi thất bại', 'error');
195
154
  }
196
155
  } catch (err) {
197
156
  if (err.name === 'NotAllowedError') {
@@ -204,7 +163,10 @@ export async function executeFromClipboard() {
204
163
  resetButton(btn);
205
164
  }
206
165
 
207
- // Make functions globally available for onclick handlers
166
+ // ==========================================
167
+ // EXPORT TO WINDOW (GLOBAL)
168
+ // ==========================================
169
+
208
170
  window.toggleSystemPrompt = toggleSystemPrompt;
209
171
  window.copySystemPrompt = copySystemPrompt;
210
172
  window.copySystemPromptFromHeader = copySystemPromptFromHeader;
@@ -212,3 +174,9 @@ window.testAnalyze = testAnalyze;
212
174
  window.copyAnalyzeResult = copyAnalyzeResult;
213
175
  window.testExecute = testExecute;
214
176
  window.executeFromClipboard = executeFromClipboard;
177
+
178
+ // Map Structure handlers from feature module to window
179
+ window.testStructure = handleStructureView;
180
+ window.toggleFolder = handleToggleFolder;
181
+ window.handleCheckboxChange = handleCheckboxChange;
182
+ window.copySelectedStructure = handleCopySelected;
@@ -2,6 +2,7 @@
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';
5
6
 
6
7
  /**
7
8
  * Initialize application on DOM ready
@@ -15,6 +16,9 @@ document.addEventListener('DOMContentLoaded', async () => {
15
16
 
16
17
  // Initialize Theme
17
18
  initTheme();
19
+
20
+ // Load Extension Path
21
+ loadExtensionPath();
18
22
  });
19
23
 
20
24
  /**
@@ -70,3 +74,59 @@ function updateThemeIcon(theme) {
70
74
  themeIcon.textContent = '🌙';
71
75
  }
72
76
  }
77
+
78
+ // Extension Helpers
79
+ async function loadExtensionPath() {
80
+ try {
81
+ const res = await fetch('/api/extension-path');
82
+ const data = await res.json();
83
+ const input = document.getElementById('extension-path-input');
84
+
85
+ if (data.exists) {
86
+ input.value = data.path;
87
+ } else {
88
+ input.value = "Error: Extension folder not found. Run 'npm run build' first.";
89
+ input.style.color = "var(--ios-red)";
90
+ }
91
+ } catch (err) {
92
+ console.error('Failed to load extension path', err);
93
+ }
94
+ }
95
+
96
+ // Expose extension handlers to window for onclick events
97
+ window.toggleExtensionGuide = function() {
98
+ const content = document.getElementById('extension-content');
99
+ const icon = document.getElementById('ext-toggle-icon');
100
+ content.classList.toggle('open');
101
+ icon.classList.toggle('open');
102
+ }
103
+
104
+ window.copyExtensionPath = function(event) {
105
+ const input = document.getElementById('extension-path-input');
106
+ const btn = event.currentTarget;
107
+ const icon = document.getElementById('ext-copy-icon');
108
+ const text = document.getElementById('ext-copy-text');
109
+
110
+ navigator.clipboard.writeText(input.value).then(() => {
111
+ showCopiedState(btn, icon, text, '📋', 'Copy Path');
112
+ showToast('Đã copy đường dẫn extension', 'success');
113
+ }).catch(err => {
114
+ showToast('Lỗi copy: ' + err.message, 'error');
115
+ });
116
+ }
117
+
118
+ window.copyChromeUrl = function(event) {
119
+ const input = document.getElementById('chrome-url-input');
120
+ const btn = event.currentTarget;
121
+ const originalText = btn.innerHTML;
122
+
123
+ navigator.clipboard.writeText(input.value).then(() => {
124
+ btn.innerHTML = '✓';
125
+ showToast('Đã copy URL', 'success');
126
+ setTimeout(() => {
127
+ btn.innerHTML = originalText;
128
+ }, 1500);
129
+ }).catch(err => {
130
+ showToast('Lỗi copy: ' + err.message, 'error');
131
+ });
132
+ }
@@ -70,3 +70,13 @@ export function showCopiedState(button, icon, text, originalIcon, originalText)
70
70
  text.textContent = originalText;
71
71
  }, 2000);
72
72
  }
73
+
74
+ /**
75
+ * Format number with commas (handles undefined/null)
76
+ * @param {number} num - Number to format
77
+ * @returns {string} Formatted string
78
+ */
79
+ export function formatNumber(num) {
80
+ if (num === undefined || num === null) return '0';
81
+ return num.toLocaleString('en-US');
82
+ }