vg-coder-cli 2.0.31 → 2.0.32

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 (40) hide show
  1. package/ARCHITECTURE.md +255 -0
  2. package/README.md +0 -11
  3. package/change.sh +0 -0
  4. package/dist/vg-coder-bundle.js +42 -0
  5. package/gulpfile.js +111 -0
  6. package/package.json +19 -11
  7. package/src/index.js +28 -220
  8. package/src/server/api-server.js +120 -428
  9. package/src/server/views/css/bubble.css +81 -0
  10. package/src/server/views/css/code-viewer.css +58 -0
  11. package/src/server/views/css/terminal.css +59 -155
  12. package/src/server/views/dashboard.css +78 -678
  13. package/src/server/views/dashboard.html +39 -278
  14. package/src/server/views/js/api.js +2 -22
  15. package/src/server/views/js/config.js +27 -15
  16. package/src/server/views/js/event-protocol.js +263 -0
  17. package/src/server/views/js/features/bubble-features/index.js +125 -0
  18. package/src/server/views/js/features/bubble-features/paste-run-feature.js +16 -0
  19. package/src/server/views/js/features/bubble-features/terminal-feature.js +16 -0
  20. package/src/server/views/js/features/bubble.js +175 -0
  21. package/src/server/views/js/features/code-viewer.js +90 -0
  22. package/src/server/views/js/features/commands.js +34 -81
  23. package/src/server/views/js/features/editor-tabs.js +19 -46
  24. package/src/server/views/js/features/git-view.js +63 -81
  25. package/src/server/views/js/features/iframe-manager.js +3 -97
  26. package/src/server/views/js/features/monaco-manager.js +19 -39
  27. package/src/server/views/js/features/project-switcher.js +7 -63
  28. package/src/server/views/js/features/resize.js +5 -16
  29. package/src/server/views/js/features/structure.js +38 -106
  30. package/src/server/views/js/features/terminal.js +102 -418
  31. package/src/server/views/js/handlers.js +60 -43
  32. package/src/server/views/js/main.js +75 -179
  33. package/src/server/views/js/shadow-entry.js +21 -0
  34. package/src/server/views/js/utils.js +48 -28
  35. package/src/server/views/vg-coder/_metadata/generated_indexed_rulesets/_ruleset1 +0 -0
  36. package/src/server/views/vg-coder/controller.js +33 -258
  37. package/vetgo-auto/chrome/src/utils/injector-script.ts +33 -258
  38. package/vetgo-auto/vg-coder.zip +0 -0
  39. package/src/server/views/dashboard.js +0 -457
  40. package/test-pty.js +0 -31
@@ -1,23 +1,23 @@
1
1
  import { getStructure, analyzeProject, copyToClipboard, saveTreeState as apiSaveTreeState, loadTreeState as apiLoadTreeState } from '../api.js';
2
- import { showToast, showLoading, resetButton, showResponse, formatNumber, showCopiedState } from '../utils.js';
2
+ import { showToast, showLoading, resetButton, showResponse, formatNumber, showCopiedState, getById, qsa } from '../utils.js';
3
3
 
4
- // Global variable to store current structure data
5
4
  let currentStructureData = null;
5
+ let excludedPaths = new Set();
6
+ let saveStateTimeout = null;
6
7
 
7
- // Tree state management
8
- let excludedPaths = new Set(); // Paths that are unchecked
9
- let saveStateTimeout = null; // Debounce timer for auto-save
10
-
11
- /**
12
- * Handle Structure button click logic
13
- */
8
+ // Exported function for Handler
14
9
  export async function handleStructureView(event) {
15
10
  const btn = event.target.closest('.btn');
16
- const pathInput = document.getElementById('structure-path');
17
- const treeContainer = document.getElementById('structure-tree');
18
- const treeContent = document.getElementById('tree-content');
19
- const errorContainer = document.getElementById('structure-response');
11
+ const pathInput = getById('structure-path');
12
+ const treeContainer = getById('structure-tree');
13
+ const treeContent = getById('tree-content');
14
+ const errorContainer = getById('structure-response');
20
15
 
16
+ if (!pathInput || !treeContainer || !treeContent || !errorContainer) {
17
+ console.error('Structure elements not found');
18
+ return;
19
+ }
20
+
21
21
  const path = pathInput.value;
22
22
 
23
23
  showLoading(btn, btn.innerHTML);
@@ -28,13 +28,10 @@ export async function handleStructureView(event) {
28
28
  const data = await getStructure(path);
29
29
  currentStructureData = data.structure;
30
30
 
31
- // Load saved state before rendering
32
31
  await loadTreeState();
33
32
 
34
- // Render Tree HTML using recursive function
35
33
  treeContent.innerHTML = generateTreeHtml(data.structure);
36
34
 
37
- // Initial token update
38
35
  updateTotalTokens();
39
36
 
40
37
  treeContainer.style.display = 'block';
@@ -48,37 +45,26 @@ export async function handleStructureView(event) {
48
45
  resetButton(btn);
49
46
  }
50
47
 
51
- /**
52
- * Toggle folder collapse/expand
53
- * Only triggers if clicked on row but NOT on checkbox
54
- */
55
48
  export function handleToggleFolder(event) {
56
49
  if (event.target.type === 'checkbox') return;
57
-
58
- // Find closest parent LI
59
50
  const li = event.currentTarget.closest('.tree-li');
60
51
  if (li && li.classList.contains('has-children')) {
61
52
  li.classList.toggle('collapsed');
62
53
  }
63
54
  }
64
55
 
65
- /**
66
- * Handle Checkbox Logic (Parent <-> Child sync) & Update Token Total
67
- */
68
56
  export function handleCheckboxChange(event) {
69
57
  event.stopPropagation();
70
58
  const checkbox = event.target;
71
59
  const isChecked = checkbox.checked;
72
60
  const path = checkbox.dataset.path;
73
61
 
74
- // 1. Update excluded paths set
75
62
  if (isChecked) {
76
63
  excludedPaths.delete(path);
77
64
  } else {
78
65
  excludedPaths.add(path);
79
66
  }
80
67
 
81
- // 2. Sync Children: If this is a folder, update all children checkboxes
82
68
  const li = checkbox.closest('.tree-li');
83
69
  if (li) {
84
70
  const childrenCheckboxes = li.querySelectorAll('.tree-checkbox');
@@ -93,54 +79,39 @@ export function handleCheckboxChange(event) {
93
79
  });
94
80
  }
95
81
 
96
- // 3. Recalculate Tokens
97
82
  updateTotalTokens();
98
-
99
- // 4. Auto-save state (debounced)
100
83
  debouncedSaveState();
101
84
  }
102
85
 
103
- /**
104
- * Calculate total tokens of CHECKED files only
105
- */
106
86
  function updateTotalTokens() {
107
- // Select all checked checkboxes that are FILES (have data-tokens)
108
- const checkedFiles = document.querySelectorAll('.tree-checkbox[data-type="file"]:checked');
109
-
87
+ const checkedFiles = qsa('.tree-checkbox[data-type="file"]:checked');
110
88
  let total = 0;
111
89
  checkedFiles.forEach(box => {
112
90
  const tokens = parseInt(box.dataset.tokens || '0');
113
91
  total += tokens;
114
92
  });
115
93
 
116
- // Update Badge
117
- const badge = document.getElementById('total-tokens-badge');
118
- badge.textContent = `${formatNumber(total)} tokens`;
119
-
120
- // Optional: Visual styling if 0
121
- if (total === 0) {
122
- badge.style.color = 'var(--ios-gray)';
123
- } else {
124
- badge.style.color = ''; // reset to default
94
+ const badge = getById('total-tokens-badge');
95
+ if (badge) {
96
+ badge.textContent = `${formatNumber(total)} tokens`;
97
+ if (total === 0) {
98
+ badge.style.color = 'var(--ios-gray)';
99
+ } else {
100
+ badge.style.color = '';
101
+ }
125
102
  }
126
103
  }
127
104
 
128
- /**
129
- * Copy Content of Selected Files (via API)
130
- */
131
105
  export async function handleCopySelected(event) {
132
106
  const btn = event.target.closest('.btn-copy') || event.target.closest('.btn-icon-head');
133
- const icon = document.getElementById('copy-structure-icon') || btn;
134
- const text = document.getElementById('copy-structure-text') || { textContent: '' };
107
+ const icon = getById('copy-structure-icon') || btn;
108
+ const text = getById('copy-structure-text') || { textContent: '' };
135
109
 
136
- // 1. Get all checked FILE paths
137
- const checkedBoxes = document.querySelectorAll('.tree-checkbox[data-type="file"]:checked');
110
+ const checkedBoxes = qsa('.tree-checkbox[data-type="file"]:checked');
138
111
  const checkedPaths = [];
139
112
 
140
113
  checkedBoxes.forEach(box => {
141
- if (box.dataset.path) {
142
- checkedPaths.push(box.dataset.path);
143
- }
114
+ if (box.dataset.path) checkedPaths.push(box.dataset.path);
144
115
  });
145
116
 
146
117
  if (checkedPaths.length === 0) {
@@ -148,30 +119,23 @@ export async function handleCopySelected(event) {
148
119
  return;
149
120
  }
150
121
 
151
- // Save original button state
152
- const originalText = btn.innerHTML;
153
122
  if (btn.classList.contains('btn-copy')) {
154
123
  showLoading(btn, btn.innerHTML);
155
124
  } else {
156
- // For header icon, just show visual feedback
157
125
  btn.style.opacity = '0.5';
158
126
  }
159
127
 
160
128
  try {
161
- const path = document.getElementById('structure-path').value;
129
+ const pathInput = getById('structure-path');
130
+ const path = pathInput ? pathInput.value : '.';
162
131
 
163
- // 2. Call Analyze API with specific files
164
132
  const content = await analyzeProject(path, checkedPaths);
165
-
166
- // 3. Copy to clipboard
167
133
  await copyToClipboard(content);
168
134
 
169
- // UI Feedback
170
135
  if (btn.classList.contains('btn-copy')) {
171
136
  showCopiedState(btn, icon, text, '📋', 'Copy Selected');
172
137
  resetButton(btn);
173
138
  } else {
174
- // Header icon feedback
175
139
  btn.style.opacity = '1';
176
140
  const originalIcon = btn.textContent;
177
141
  btn.textContent = '✓';
@@ -187,20 +151,13 @@ export async function handleCopySelected(event) {
187
151
  }
188
152
  }
189
153
 
190
- /**
191
- * Recursive function to generate Tree HTML with Checkboxes
192
- */
193
154
  function generateTreeHtml(node) {
194
155
  if (!node) return '';
195
156
 
196
- // --- COMPACT FOLDER LOGIC ---
197
157
  let currentNode = node;
198
158
  let displayName = node.name;
199
- let isCompact = false;
200
159
 
201
- // Only compact if it's a directory
202
160
  if (currentNode.type === 'directory') {
203
- // While current node has EXACTLY one child and that child is a directory
204
161
  while (
205
162
  currentNode.children &&
206
163
  currentNode.children.length === 1 &&
@@ -208,30 +165,22 @@ function generateTreeHtml(node) {
208
165
  ) {
209
166
  const child = currentNode.children[0];
210
167
  displayName += '/' + child.name;
211
- currentNode = child; // Advance to child
212
- isCompact = true;
168
+ currentNode = child;
213
169
  }
214
170
  }
215
171
 
216
- // Now uses 'currentNode' for properties (it's the deepest folder in the chain)
217
- // But we use 'displayName' for the UI
218
- // 'tokens' should be from the root node of this chain (usually same as leaf for folders)
219
-
220
172
  const isDir = currentNode.type === 'directory';
221
173
  const hasChildren = isDir && currentNode.children && currentNode.children.length > 0;
222
-
223
- // Determine Token Color (Use original node's tokens or deep node's tokens - they should be identical)
224
174
  const tokens = currentNode.tokens || 0;
175
+
225
176
  let tokenClass = 'token-low';
226
177
  if (tokens > 5000) tokenClass = 'token-high';
227
178
  else if (tokens > 2000) tokenClass = 'token-med';
228
179
 
229
- // Icon
230
180
  const icon = isDir ? (hasChildren ? '📁' : '📂') : '📄';
231
181
  const arrow = hasChildren ? '▼' : '';
232
182
  const liClass = `tree-li ${hasChildren ? 'has-children' : ''}`;
233
183
 
234
- // Actions
235
184
  let clickAction = '';
236
185
  let cursorStyle = '';
237
186
 
@@ -241,17 +190,13 @@ function generateTreeHtml(node) {
241
190
  cursorStyle = 'cursor: pointer;';
242
191
  }
243
192
  } else {
244
- // File click -> Open in Editor
245
- // Escape backslashes for Windows paths
246
193
  const safePath = (currentNode.relativePath || currentNode.path).replace(/\\/g, '\\\\');
247
194
  clickAction = `onclick="window.openFileTab('${safePath}', '${currentNode.name}')"`;
248
195
  cursorStyle = 'cursor: pointer; color: var(--text-primary);';
249
196
  }
250
197
 
251
- // Build HTML
252
198
  let html = `<li class="${liClass}">`;
253
199
 
254
- // Check if this path should be excluded (unchecked)
255
200
  const nodePath = currentNode.relativePath || currentNode.path;
256
201
  const isExcluded = excludedPaths.has(nodePath);
257
202
 
@@ -270,10 +215,8 @@ function generateTreeHtml(node) {
270
215
  </div>
271
216
  `;
272
217
 
273
- // Children recursion (using deepest node's children)
274
218
  if (hasChildren) {
275
219
  html += '<ul class="tree-ul">';
276
- // Sort: Folders first, then files
277
220
  currentNode.children.forEach(child => {
278
221
  html += generateTreeHtml(child);
279
222
  });
@@ -281,48 +224,37 @@ function generateTreeHtml(node) {
281
224
  }
282
225
 
283
226
  html += '</li>';
284
-
285
227
  return isDir ? `<ul class="tree-ul">${html}</ul>` : html;
286
228
  }
287
229
 
288
- /**
289
- * Load tree state from backend
290
- */
291
230
  async function loadTreeState() {
292
231
  try {
293
232
  const data = await apiLoadTreeState();
294
233
  excludedPaths = new Set(data.excludedPaths || []);
295
- console.log(`Loaded tree state: ${excludedPaths.size} excluded items`);
296
234
  } catch (err) {
297
235
  console.error('Failed to load tree state:', err);
298
- excludedPaths = new Set(); // Reset to empty on error
236
+ excludedPaths = new Set();
299
237
  }
300
238
  }
301
239
 
302
- /**
303
- * Debounced save - waits 500ms after last change before saving
304
- */
305
240
  function debouncedSaveState() {
306
- // Clear existing timeout
307
- if (saveStateTimeout) {
308
- clearTimeout(saveStateTimeout);
309
- }
310
-
311
- // Set new timeout
241
+ if (saveStateTimeout) clearTimeout(saveStateTimeout);
312
242
  saveStateTimeout = setTimeout(() => {
313
243
  saveTreeState();
314
244
  }, 500);
315
245
  }
316
246
 
317
- /**
318
- * Save current tree state to backend
319
- */
320
247
  async function saveTreeState() {
321
248
  try {
322
249
  const excludedArray = Array.from(excludedPaths);
323
250
  await apiSaveTreeState(excludedArray);
324
- console.log(`Saved tree state: ${excludedArray.length} excluded items`);
325
251
  } catch (err) {
326
252
  console.error('Failed to save tree state:', err);
327
253
  }
328
254
  }
255
+
256
+ // FIX: Expose functions to window so HTML onclick works
257
+ window.testStructure = handleStructureView;
258
+ window.toggleFolder = handleToggleFolder;
259
+ window.handleCheckboxChange = handleCheckboxChange;
260
+ window.copySelectedStructure = handleCopySelected;