vg-coder-cli 2.0.34 → 2.0.36

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vg-coder-cli",
3
- "version": "2.0.34",
3
+ "version": "2.0.36",
4
4
  "description": "🚀 CLI tool to analyze projects, concatenate source files, count tokens, and export HTML with syntax highlighting and copy functionality",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -47,7 +47,6 @@
47
47
  "socket.io": "^4.7.2",
48
48
  "socket.io-client": "^4.8.3",
49
49
  "tiktoken": "^1.0.10",
50
- "vg-coder-cli": "^2.0.15",
51
50
  "xterm": "^5.3.0",
52
51
  "xterm-addon-fit": "^0.8.0"
53
52
  },
@@ -136,6 +136,25 @@ class ApiServer {
136
136
  res.send(content);
137
137
  });
138
138
 
139
+ // Count tokens using TokenManager (tiktoken)
140
+ this.app.post('/api/count-tokens', async (req, res) => {
141
+ try {
142
+ const { text } = req.body;
143
+
144
+ if (!text) {
145
+ return res.json({ tokens: 0 });
146
+ }
147
+
148
+ const tokenManager = new TokenManager();
149
+ const tokens = tokenManager.countTokens(text);
150
+
151
+ res.json({ tokens });
152
+ } catch (error) {
153
+ console.error('Token counting error:', error);
154
+ res.status(500).json({ error: error.message, tokens: 0 });
155
+ }
156
+ });
157
+
139
158
  // --- PROJECT MANAGEMENT APIS (FIXED) ---
140
159
 
141
160
  // List all projects
@@ -238,6 +257,117 @@ class ApiServer {
238
257
  }
239
258
  });
240
259
 
260
+ // Git Stage
261
+ this.app.post('/api/git/stage', async (req, res) => {
262
+ try {
263
+ const { files } = req.body;
264
+ const fileList = Array.isArray(files) ? files : [files];
265
+
266
+ if (fileList.includes('*')) {
267
+ await execAsync('git add -A', { cwd: req.workingDir });
268
+ } else {
269
+ for (const file of fileList) {
270
+ await execAsync(`git add "${file}"`, { cwd: req.workingDir });
271
+ }
272
+ }
273
+
274
+ res.json({ success: true });
275
+ } catch (error) {
276
+ res.status(500).json({ error: error.message });
277
+ }
278
+ });
279
+
280
+ // Git Unstage
281
+ this.app.post('/api/git/unstage', async (req, res) => {
282
+ try {
283
+ const { files } = req.body;
284
+ const fileList = Array.isArray(files) ? files : [files];
285
+
286
+ if (fileList.includes('*')) {
287
+ await execAsync('git reset HEAD', { cwd: req.workingDir });
288
+ } else {
289
+ for (const file of fileList) {
290
+ await execAsync(`git reset HEAD "${file}"`, { cwd: req.workingDir });
291
+ }
292
+ }
293
+
294
+ res.json({ success: true });
295
+ } catch (error) {
296
+ res.status(500).json({ error: error.message });
297
+ }
298
+ });
299
+
300
+ // Git Commit
301
+ this.app.post('/api/git/commit', async (req, res) => {
302
+ try {
303
+ const { message } = req.body;
304
+
305
+ if (!message || !message.trim()) {
306
+ return res.status(400).json({ error: 'Commit message is required' });
307
+ }
308
+
309
+ await execAsync(`git commit -m "${message.replace(/"/g, '\\"')}"`, { cwd: req.workingDir });
310
+ res.json({ success: true });
311
+ } catch (error) {
312
+ res.status(500).json({ error: error.message });
313
+ }
314
+ });
315
+
316
+ // Git Discard
317
+ this.app.post('/api/git/discard', async (req, res) => {
318
+ try {
319
+ const { files } = req.body;
320
+ const fileList = Array.isArray(files) ? files : [files];
321
+
322
+ if (fileList.includes('*')) {
323
+ // Discard all changes
324
+ await execAsync('git checkout -- .', { cwd: req.workingDir });
325
+ // Clean untracked files
326
+ await execAsync('git clean -fd', { cwd: req.workingDir });
327
+ } else {
328
+ for (const file of fileList) {
329
+ // Check if file is tracked
330
+ try {
331
+ await execAsync(`git ls-files --error-unmatch "${file}"`, { cwd: req.workingDir });
332
+ // Tracked file - checkout
333
+ await execAsync(`git checkout -- "${file}"`, { cwd: req.workingDir });
334
+ } catch (e) {
335
+ // Untracked file - remove
336
+ await execAsync(`rm "${file}"`, { cwd: req.workingDir });
337
+ }
338
+ }
339
+ }
340
+
341
+ res.json({ success: true });
342
+ } catch (error) {
343
+ res.status(500).json({ error: error.message });
344
+ }
345
+ });
346
+
347
+ // Git Push
348
+ this.app.post('/api/git/push', async (req, res) => {
349
+ try {
350
+ const { remote = 'origin', branch } = req.body;
351
+
352
+ // Get current branch if not specified
353
+ let currentBranch = branch;
354
+ if (!currentBranch) {
355
+ const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD', { cwd: req.workingDir });
356
+ currentBranch = stdout.trim();
357
+ }
358
+
359
+ // Push to remote
360
+ await execAsync(`git push ${remote} ${currentBranch}`, {
361
+ cwd: req.workingDir,
362
+ timeout: 30000 // 30 seconds timeout
363
+ });
364
+
365
+ res.json({ success: true, branch: currentBranch, remote });
366
+ } catch (error) {
367
+ res.status(500).json({ error: error.message });
368
+ }
369
+ });
370
+
241
371
  // Tree State API
242
372
  this.app.post('/api/tree-state/save', async (req, res) => {
243
373
  try {
@@ -0,0 +1,75 @@
1
+ /* Commands Panel Styles */
2
+ #commands-panel-content {
3
+ padding: 0;
4
+ background: #2B2D30;
5
+ }
6
+
7
+ [data-theme="light"] #commands-panel-content {
8
+ background: #FFFFFF;
9
+ }
10
+
11
+ .commands-panel-header {
12
+ padding: 12px;
13
+ border-bottom: 1px solid #1E1F22;
14
+ background: #2B2D30;
15
+ display: flex;
16
+ gap: 8px;
17
+ }
18
+
19
+ [data-theme="light"] .commands-panel-header {
20
+ background: #F7F7F7;
21
+ border-bottom: 1px solid #D1D1D1;
22
+ }
23
+
24
+ .commands-panel-btn {
25
+ flex: 1;
26
+ padding: 8px 12px;
27
+ background: #4E84E8;
28
+ color: white;
29
+ border: none;
30
+ border-radius: 4px;
31
+ cursor: pointer;
32
+ font-size: 12px;
33
+ font-weight: 500;
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ gap: 6px;
38
+ transition: background 0.15s ease;
39
+ }
40
+
41
+ .commands-panel-btn:hover {
42
+ background: #3A6FBF;
43
+ }
44
+
45
+ [data-theme="light"] .commands-panel-btn {
46
+ background: #007AFF;
47
+ }
48
+
49
+ [data-theme="light"] .commands-panel-btn:hover {
50
+ background: #0051D5;
51
+ }
52
+
53
+ /* Commands Content Area */
54
+ .saved-commands-content {
55
+ padding: 0;
56
+ }
57
+
58
+ .commands-list {
59
+ padding: 8px;
60
+ }
61
+
62
+ .commands-empty-state {
63
+ padding: 40px 20px;
64
+ text-align: center;
65
+ }
66
+
67
+ .commands-empty-state p {
68
+ color: #868A8E;
69
+ font-size: 13px;
70
+ margin: 0;
71
+ }
72
+
73
+ [data-theme="light"] .commands-empty-state p {
74
+ color: #6E6E6E;
75
+ }
@@ -32,7 +32,6 @@
32
32
 
33
33
  /* Khu vực Actions bên phải */
34
34
  .tabs-actions {
35
- display: flex;
36
35
  align-items: center;
37
36
  padding: 0 5px;
38
37
  background: #252526;
@@ -40,6 +39,7 @@
40
39
  border-left: 1px solid #1e1e1e;
41
40
  box-shadow: -5px 0 10px rgba(0,0,0,0.2); /* Tạo bóng đổ nhẹ ngăn cách */
42
41
  z-index: 5;
42
+ display: none; /* để trigger đóng view code change */
43
43
  }
44
44
 
45
45
  /* Style cho Tab Item */
@@ -0,0 +1,361 @@
1
+ /* Git Panel Styles - IDE-Style */
2
+
3
+ /* Override tool-panel-content for git-specific styling */
4
+ #git-panel-content {
5
+ padding: 0;
6
+ background: #1E1F22;
7
+ }
8
+
9
+ [data-theme="light"] #git-panel-content {
10
+ background: #FFFFFF;
11
+ }
12
+
13
+ /* Commit Section */
14
+ .git-panel-commit-section {
15
+ padding: 10px;
16
+ border-bottom: 1px solid #1E1F22;
17
+ background: #2B2D30;
18
+ }
19
+
20
+ [data-theme="light"] .git-panel-commit-section {
21
+ background: #F7F7F7;
22
+ border-bottom: 1px solid #D1D1D1;
23
+ }
24
+
25
+ .git-panel-commit-input {
26
+ width: 100%;
27
+ background: #1E1F22;
28
+ border: 1px solid #1E1F22;
29
+ color: #DFE1E5;
30
+ padding: 6px 8px;
31
+ border-radius: 4px;
32
+ font-family: inherit;
33
+ font-size: 12px;
34
+ resize: vertical;
35
+ min-height: 60px;
36
+ margin-bottom: 8px;
37
+ }
38
+
39
+ [data-theme="light"] .git-panel-commit-input {
40
+ background: #FFFFFF;
41
+ border: 1px solid #D1D1D1;
42
+ color: #000000;
43
+ }
44
+
45
+ .git-panel-commit-input:focus {
46
+ outline: 1px solid #4E84E8;
47
+ border-color: #4E84E8;
48
+ }
49
+
50
+ [data-theme="light"] .git-panel-commit-input:focus {
51
+ outline: 1px solid #007AFF;
52
+ border-color: #007AFF;
53
+ }
54
+
55
+ .git-panel-commit-btn {
56
+ width: 100%;
57
+ background: #4E84E8;
58
+ color: white;
59
+ border: none;
60
+ padding: 6px 12px;
61
+ border-radius: 4px;
62
+ cursor: pointer;
63
+ font-size: 12px;
64
+ font-weight: 500;
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: center;
68
+ gap: 6px;
69
+ transition: background 0.15s ease;
70
+ }
71
+
72
+ .git-panel-commit-btn:hover {
73
+ background: #3A6FBF;
74
+ }
75
+
76
+ [data-theme="light"] .git-panel-commit-btn {
77
+ background: #007AFF;
78
+ }
79
+
80
+ [data-theme="light"] .git-panel-commit-btn:hover {
81
+ background: #0051D5;
82
+ }
83
+
84
+ .git-panel-commit-btn:disabled {
85
+ background: #30363d;
86
+ color: #8b949e;
87
+ cursor: not-allowed;
88
+ }
89
+
90
+ /* Section Headers */
91
+ .git-panel-section-header {
92
+ padding: 8px 12px;
93
+ font-size: 11px;
94
+ font-weight: bold;
95
+ text-transform: uppercase;
96
+ color: #868A8E;
97
+ background: #1E1F22;
98
+ display: flex;
99
+ justify-content: space-between;
100
+ align-items: center;
101
+ cursor: default;
102
+ border-bottom: 1px solid #1E1F22;
103
+ position: sticky;
104
+ top: 0;
105
+ z-index: 10;
106
+ }
107
+
108
+ [data-theme="light"] .git-panel-section-header {
109
+ background: #F2F2F2;
110
+ border-bottom: 1px solid #D1D1D1;
111
+ }
112
+
113
+ .git-panel-badge {
114
+ background: #30363d;
115
+ color: #c9d1d9;
116
+ padding: 2px 6px;
117
+ border-radius: 10px;
118
+ font-size: 10px;
119
+ min-width: 18px;
120
+ text-align: center;
121
+ }
122
+
123
+ [data-theme="light"] .git-panel-badge {
124
+ background: #E8E8E8;
125
+ color: #000000;
126
+ }
127
+
128
+ /* Tree */
129
+ .git-panel-tree {
130
+ list-style: none;
131
+ padding: 0;
132
+ margin: 0;
133
+ }
134
+
135
+ .git-panel-tree-node {
136
+ list-style: none;
137
+ }
138
+
139
+ .git-panel-tree-content {
140
+ display: flex;
141
+ align-items: center;
142
+ padding: 4px 8px;
143
+ cursor: pointer;
144
+ font-size: 12px;
145
+ min-height: 24px;
146
+ color: #DFE1E5;
147
+ white-space: nowrap;
148
+ transition: background 0.1s ease;
149
+ }
150
+
151
+ [data-theme="light"] .git-panel-tree-content {
152
+ color: #000000;
153
+ }
154
+
155
+ .git-panel-tree-content:hover {
156
+ background: rgba(255, 255, 255, 0.08);
157
+ }
158
+
159
+ [data-theme="light"] .git-panel-tree-content:hover {
160
+ background: rgba(0, 0, 0, 0.05);
161
+ }
162
+
163
+ .git-panel-tree-content.selected {
164
+ background: rgba(78, 132, 232, 0.2);
165
+ color: #FFFFFF;
166
+ }
167
+
168
+ [data-theme="light"] .git-panel-tree-content.selected {
169
+ background: rgba(0, 122, 255, 0.15);
170
+ color: #000000;
171
+ }
172
+
173
+ .git-panel-arrow {
174
+ width: 14px;
175
+ text-align: center;
176
+ font-size: 10px;
177
+ color: #868A8E;
178
+ transition: transform 0.15s;
179
+ display: inline-block;
180
+ flex-shrink: 0;
181
+ margin-right: 2px;
182
+ }
183
+
184
+ .git-panel-tree-node.collapsed > .git-panel-tree-content > .git-panel-arrow {
185
+ transform: rotate(-90deg);
186
+ }
187
+
188
+ .git-panel-tree-node.collapsed > ul {
189
+ display: none;
190
+ }
191
+
192
+ .git-panel-icon {
193
+ margin-right: 6px;
194
+ font-weight: bold;
195
+ width: 16px;
196
+ text-align: center;
197
+ flex-shrink: 0;
198
+ font-size: 14px;
199
+ }
200
+
201
+ /* Status Colors */
202
+ .git-status-M {
203
+ color: #d29922;
204
+ }
205
+
206
+ .git-status-A,
207
+ .git-status-U {
208
+ color: #3fb950;
209
+ }
210
+
211
+ .git-status-D {
212
+ color: #f85149;
213
+ text-decoration: line-through;
214
+ }
215
+
216
+ .git-status-R {
217
+ color: #d29922;
218
+ }
219
+
220
+ .git-panel-label {
221
+ flex: 1;
222
+ overflow: hidden;
223
+ text-overflow: ellipsis;
224
+ white-space: nowrap;
225
+ font-size: 12px;
226
+ }
227
+
228
+ .git-panel-dir-label {
229
+ color: #DFE1E5;
230
+ }
231
+
232
+ [data-theme="light"] .git-panel-dir-label {
233
+ color: #000000;
234
+ }
235
+
236
+ .git-panel-file-label {
237
+ color: #868A8E;
238
+ }
239
+
240
+ .git-panel-tree-content:hover .git-panel-file-label,
241
+ .git-panel-tree-content.selected .git-panel-file-label {
242
+ color: #DFE1E5;
243
+ }
244
+
245
+ [data-theme="light"] .git-panel-tree-content:hover .git-panel-file-label,
246
+ [data-theme="light"] .git-panel-tree-content.selected .git-panel-file-label {
247
+ color: #000000;
248
+ }
249
+
250
+ /* Actions */
251
+ .git-panel-actions {
252
+ display: none;
253
+ margin-left: 6px;
254
+ flex-shrink: 0;
255
+ gap: 4px;
256
+ }
257
+
258
+ .git-panel-tree-content:hover .git-panel-actions {
259
+ display: flex;
260
+ }
261
+
262
+ .git-panel-btn-action {
263
+ background: transparent;
264
+ border: none;
265
+ color: #868A8E;
266
+ cursor: pointer;
267
+ padding: 0 4px;
268
+ border-radius: 4px;
269
+ font-size: 12px;
270
+ line-height: 1;
271
+ transition: all 0.15s ease;
272
+ }
273
+
274
+ .git-panel-btn-action:hover {
275
+ background: rgba(255, 255, 255, 0.1);
276
+ color: #DFE1E5;
277
+ }
278
+
279
+ [data-theme="light"] .git-panel-btn-action:hover {
280
+ background: rgba(0, 0, 0, 0.08);
281
+ color: #000000;
282
+ }
283
+
284
+ .git-panel-btn-action.destructive:hover {
285
+ background: #f85149;
286
+ color: #fff;
287
+ }
288
+
289
+ /* Section Actions */
290
+ .git-panel-section-actions {
291
+ display: flex;
292
+ gap: 8px;
293
+ }
294
+
295
+ .git-panel-section-action-btn {
296
+ background: transparent;
297
+ border: none;
298
+ color: #868A8E;
299
+ cursor: pointer;
300
+ font-size: 12px;
301
+ padding: 2px 4px;
302
+ border-radius: 4px;
303
+ transition: all 0.15s ease;
304
+ }
305
+
306
+ .git-panel-section-action-btn:hover {
307
+ background: rgba(255, 255, 255, 0.1);
308
+ color: #DFE1E5;
309
+ }
310
+
311
+ [data-theme="light"] .git-panel-section-action-btn:hover {
312
+ background: rgba(0, 0, 0, 0.08);
313
+ color: #000000;
314
+ }
315
+
316
+ /* Empty State */
317
+ .git-panel-empty {
318
+ padding: 20px;
319
+ text-align: center;
320
+ color: #868A8E;
321
+ font-size: 12px;
322
+ }
323
+
324
+ /* Loading */
325
+ .git-panel-loading {
326
+ padding: 20px;
327
+ text-align: center;
328
+ color: #868A8E;
329
+ font-size: 12px;
330
+ }
331
+ .git-panel-commit-btn:disabled {
332
+ background: #30363d;
333
+ color: #8b949e;
334
+ cursor: not-allowed;
335
+ }
336
+
337
+ /* Push Button */
338
+ .git-panel-push-btn {
339
+ background: transparent;
340
+ border: 1px solid #30363d;
341
+ color: #8b949e;
342
+ padding: 4px 10px;
343
+ border-radius: 4px;
344
+ cursor: pointer;
345
+ font-size: 11px;
346
+ font-weight: 600;
347
+ transition: all 0.2s;
348
+ }
349
+
350
+ .git-panel-push-btn:hover:not(:disabled) {
351
+ background: #238636;
352
+ border-color: #238636;
353
+ color: white;
354
+ }
355
+
356
+ .git-panel-push-btn:disabled {
357
+ opacity: 0.5;
358
+ cursor: not-allowed;
359
+ }
360
+
361
+ /* Section Headers */
@@ -29,22 +29,10 @@
29
29
  border-color: var(--ios-blue);
30
30
  }
31
31
 
32
- .git-refresh-btn {
33
- width: 32px;
34
- height: 32px;
35
- border-radius: 6px;
36
- border: 1px solid var(--ios-separator);
37
- background: var(--ios-card);
38
- color: var(--text-primary);
39
- cursor: pointer;
40
- display: flex;
41
- align-items: center;
42
- justify-content: center;
43
- }
44
32
 
45
33
  .git-view-container {
46
34
  position: absolute;
47
- top: 35px;
35
+ top: 0px;
48
36
  left: 0;
49
37
  right: 0;
50
38
  bottom: 0;
@@ -57,73 +45,9 @@
57
45
 
58
46
  .git-view-container.active {
59
47
  display: flex;
60
- }
61
48
 
62
- /* --- SIDEBAR --- */
63
- .git-sidebar {
64
- width: 300px;
65
- min-width: 250px;
66
- background: #0d1117;
67
- border-right: 1px solid #30363d;
68
- display: flex;
69
- flex-direction: column;
70
- overflow-y: auto;
71
- color: #c9d1d9;
72
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
73
- user-select: none;
74
- }
75
49
 
76
- /* --- COMMIT SECTION --- */
77
- .git-commit-section {
78
- padding: 10px;
79
- border-bottom: 1px solid #30363d;
80
- background: #0d1117;
81
- }
82
50
 
83
- .git-commit-input {
84
- width: 100%;
85
- background: #161b22;
86
- border: 1px solid #30363d;
87
- color: #c9d1d9;
88
- padding: 6px 8px;
89
- border-radius: 4px;
90
- font-family: inherit;
91
- font-size: 13px;
92
- resize: vertical;
93
- min-height: 32px;
94
- margin-bottom: 8px;
95
- }
96
-
97
- .git-commit-input:focus {
98
- outline: 1px solid #58a6ff;
99
- border-color: #58a6ff;
100
- }
101
-
102
- .git-commit-btn {
103
- width: 100%;
104
- background: #0078d4;
105
- color: white;
106
- border: none;
107
- padding: 6px 12px;
108
- border-radius: 2px;
109
- cursor: pointer;
110
- font-size: 13px;
111
- font-weight: 500;
112
- display: flex;
113
- align-items: center;
114
- justify-content: center;
115
- gap: 6px;
116
- }
117
-
118
- .git-commit-btn:hover {
119
- background: #026ec1;
120
- }
121
-
122
- .git-commit-btn:disabled {
123
- background: #30363d;
124
- color: #8b949e;
125
- cursor: not-allowed;
126
- }
127
51
 
128
52
  /* --- SECTIONS & TREE --- */
129
53
  .git-section {