vg-coder-cli 1.0.11 → 1.0.12

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": "1.0.11",
3
+ "version": "1.0.12",
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": {
@@ -1,5 +1,6 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
+
3
4
  <head>
4
5
  <meta charset="UTF-8">
5
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -28,7 +29,7 @@
28
29
  border-radius: 12px;
29
30
  padding: 30px;
30
31
  margin-bottom: 30px;
31
- box-shadow: 0 10px 30px rgba(0,0,0,0.2);
32
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
32
33
  }
33
34
 
34
35
  .header h1 {
@@ -62,7 +63,7 @@
62
63
  background: white;
63
64
  border-radius: 12px;
64
65
  padding: 25px;
65
- box-shadow: 0 10px 30px rgba(0,0,0,0.2);
66
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
66
67
  transition: transform 0.3s ease;
67
68
  }
68
69
 
@@ -84,9 +85,20 @@
84
85
  font-size: 0.85em;
85
86
  }
86
87
 
87
- .method.get { background: #3b82f6; color: white; }
88
- .method.post { background: #10b981; color: white; }
89
- .method.delete { background: #ef4444; color: white; }
88
+ .method.get {
89
+ background: #3b82f6;
90
+ color: white;
91
+ }
92
+
93
+ .method.post {
94
+ background: #10b981;
95
+ color: white;
96
+ }
97
+
98
+ .method.delete {
99
+ background: #ef4444;
100
+ color: white;
101
+ }
90
102
 
91
103
  .endpoint-path {
92
104
  font-family: 'Courier New', monospace;
@@ -182,17 +194,92 @@
182
194
  display: inline-block;
183
195
  width: 16px;
184
196
  height: 16px;
185
- border: 3px solid rgba(255,255,255,.3);
197
+ border: 3px solid rgba(255, 255, 255, .3);
186
198
  border-radius: 50%;
187
199
  border-top-color: white;
188
200
  animation: spin 1s ease-in-out infinite;
189
201
  }
190
202
 
191
203
  @keyframes spin {
192
- to { transform: rotate(360deg); }
204
+ to {
205
+ transform: rotate(360deg);
206
+ }
207
+ }
208
+
209
+ .system-prompt-card {
210
+ background: white;
211
+ border-radius: 12px;
212
+ padding: 25px;
213
+ margin-bottom: 30px;
214
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
215
+ }
216
+
217
+ .system-prompt-header {
218
+ display: flex;
219
+ justify-content: space-between;
220
+ align-items: center;
221
+ margin-bottom: 15px;
222
+ cursor: pointer;
223
+ user-select: none;
224
+ }
225
+
226
+ .system-prompt-header h2 {
227
+ color: #667eea;
228
+ font-size: 1.5em;
229
+ display: flex;
230
+ align-items: center;
231
+ gap: 10px;
232
+ }
233
+
234
+ .toggle-icon {
235
+ transition: transform 0.3s ease;
236
+ }
237
+
238
+ .toggle-icon.open {
239
+ transform: rotate(180deg);
240
+ }
241
+
242
+ .system-prompt-content {
243
+ max-height: 0;
244
+ overflow: hidden;
245
+ transition: max-height 0.3s ease;
246
+ }
247
+
248
+ .system-prompt-content.open {
249
+ max-height: 2000px;
250
+ }
251
+
252
+ .prompt-text {
253
+ background: #f9fafb;
254
+ border: 2px solid #e5e7eb;
255
+ border-radius: 8px;
256
+ padding: 20px;
257
+ font-family: 'Courier New', monospace;
258
+ font-size: 0.9em;
259
+ line-height: 1.6;
260
+ white-space: pre-wrap;
261
+ max-height: 400px;
262
+ overflow-y: auto;
263
+ margin-bottom: 15px;
264
+ }
265
+
266
+ .btn-copy {
267
+ background: #10b981;
268
+ display: inline-flex;
269
+ align-items: center;
270
+ gap: 8px;
271
+ }
272
+
273
+ .btn-copy:hover {
274
+ background: #059669;
275
+ }
276
+
277
+ .btn-copy.copied {
278
+ background: #6366f1;
193
279
  }
194
280
  </style>
195
281
  </head>
282
+
196
283
  <body>
197
284
  <div class="container">
198
285
  <div class="header">
@@ -201,6 +288,24 @@
201
288
  <span class="status" id="status">● Server Running</span>
202
289
  </div>
203
290
 
291
+ <!-- System Prompt Section -->
292
+ <div class="system-prompt-card">
293
+ <div class="system-prompt-header" onclick="toggleSystemPrompt()">
294
+ <h2>
295
+ <span>📝</span>
296
+ <span>AI System Prompt</span>
297
+ </h2>
298
+ <span class="toggle-icon" id="toggle-icon">▼</span>
299
+ </div>
300
+ <div class="system-prompt-content" id="system-prompt-content">
301
+ <div class="prompt-text" id="prompt-text"></div>
302
+ <button class="btn btn-copy" onclick="copySystemPrompt()">
303
+ <span id="copy-icon">📋</span>
304
+ <span id="copy-text">Copy System Prompt</span>
305
+ </button>
306
+ </div>
307
+ </div>
308
+
204
309
  <div class="endpoints">
205
310
  <!-- Health Check -->
206
311
  <div class="endpoint-card">
@@ -315,14 +420,14 @@
315
420
  const btn = event.target;
316
421
  const path = document.getElementById('analyze-path').value;
317
422
  const maxTokens = document.getElementById('analyze-tokens').value;
318
-
423
+
319
424
  showLoading(btn);
320
425
  try {
321
426
  const res = await fetch(`${API_BASE}/api/analyze`, {
322
427
  method: 'POST',
323
428
  headers: { 'Content-Type': 'application/json' },
324
- body: JSON.stringify({
325
- path,
429
+ body: JSON.stringify({
430
+ path,
326
431
  options: { maxTokens: parseInt(maxTokens) }
327
432
  })
328
433
  });
@@ -348,7 +453,7 @@
348
453
  async function testInfo() {
349
454
  const btn = event.target;
350
455
  const path = document.getElementById('info-path').value;
351
-
456
+
352
457
  showLoading(btn);
353
458
  try {
354
459
  const res = await fetch(`${API_BASE}/api/info?path=${encodeURIComponent(path)}`);
@@ -363,7 +468,7 @@
363
468
  async function testExecute() {
364
469
  const btn = event.target;
365
470
  const bash = document.getElementById('execute-bash').value;
366
-
471
+
367
472
  if (!bash.trim()) {
368
473
  showResponse('execute-response', { error: 'Bash script is required' }, true);
369
474
  return;
@@ -387,7 +492,7 @@
387
492
  async function testClean() {
388
493
  const btn = event.target;
389
494
  const output = document.getElementById('clean-output').value;
390
-
495
+
391
496
  showLoading(btn);
392
497
  try {
393
498
  const res = await fetch(`${API_BASE}/api/clean`, {
@@ -403,19 +508,171 @@
403
508
  resetButton(btn, 'Clean Directory');
404
509
  }
405
510
 
406
- // Check server status periodically
407
- setInterval(async () => {
511
+ // System Prompt
512
+ const SYSTEM_PROMPT = `# VG Coder AI System Prompt
513
+
514
+ ## Command Prefixes
515
+
516
+ ### /ask - Question & Answer Mode
517
+ 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 đề.
518
+
519
+ **Response Format:** Markdown
520
+ - Trả lời chi tiết, rõ ràng
521
+ - Sử dụng code blocks, lists, tables khi cần
522
+ - Cung cấp ví dụ minh họa
523
+
524
+ ---
525
+
526
+ ### /plan - Planning Mode
527
+ 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.
528
+
529
+ **Response Format:** Markdown checklist với bash commands
530
+ - Chia nhỏ thành các bước cụ thể
531
+ - Mỗi bước có bash command tương ứng
532
+ - Sắp xếp theo thứ tự logic
533
+
534
+ ---
535
+
536
+ ### /fix - Bug Fix Mode
537
+ 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.
538
+
539
+ **Response Format:** Markdown + Bash script
540
+ 1. **Phân tích lỗi:** Giải thích nguyên nhân
541
+ 2. **Giải pháp:** Mô tả cách fix
542
+ 3. **Bash script:** Code để fix (nếu cần)
543
+
544
+ ---
545
+
546
+ ### /code - Code Generation Mode
547
+ 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.
548
+
549
+ ## ⚠️ QUY TẮC BẮT BUỘC
550
+
551
+ ### 1. Chỉ bao gồm files có thay đổi
552
+ - ❌ **KHÔNG** bao gồm files không có sự thay đổi nội dung
553
+ - ✅ Nếu nội dung file sau chỉnh sửa giống 100% bản cũ → **BỎ QUA**
554
+
555
+ ### 2. Format Script Chuẩn
556
+
557
+ **Mỗi file PHẢI theo cú pháp:**
558
+ \`\`\`bash
559
+ mkdir -p $(dirname "path/to/file.ext")
560
+ cat <<'EOF' > path/to/file.ext
561
+ ... toàn bộ nội dung file sau khi chỉnh sửa ...
562
+ EOF
563
+ \`\`\`
564
+
565
+ ### 3. Chi tiết quan trọng
566
+ - ✅ **LUÔN** có \`mkdir -p $(dirname "...")\` trước mỗi file
567
+ - ✅ Sử dụng \`<<'EOF'\` (có dấu nháy đơn) để tránh bash expansion
568
+ - ✅ Ghi đè hoàn toàn file bằng nội dung mới
569
+ - ✅ Tự động tạo file và thư mục cha nếu chưa tồn tại
570
+ - ✅ Đường dẫn giống với file mẫu đính kèm
571
+
572
+ ### 4. Example Output
573
+
574
+ \`\`\`bash
575
+ # Create/Update component file
576
+ mkdir -p $(dirname "src/components/Button/index.tsx")
577
+ cat <<'EOF' > src/components/Button/index.tsx
578
+ import React from 'react';
579
+
580
+ export const Button = () => {
581
+ return <button>Click me</button>;
582
+ };
583
+ EOF
584
+
585
+ # Create/Update styles
586
+ mkdir -p $(dirname "src/components/Button/styles.css")
587
+ cat <<'EOF' > src/components/Button/styles.css
588
+ .button {
589
+ padding: 10px 20px;
590
+ background: blue;
591
+ }
592
+ EOF
593
+ \`\`\`
594
+
595
+ ---
596
+
597
+ ## Integration với VG Coder CLI
598
+
599
+ Bash scripts được generate sẽ được thực thi qua:
600
+ \`\`\`bash
601
+ POST http://localhost:6868/api/execute
602
+ {
603
+ "bash": "mkdir -p $(dirname \\"src/...\\")\\\\ncat <<'EOF' > ..."
604
+ }
605
+ \`\`\`
606
+
607
+ API sẽ:
608
+ 1. ✅ Validate bash syntax trong \`.vg/temp-execute\`
609
+ 2. ✅ Execute tại working directory nếu syntax OK
610
+ 3. ✅ Trả về stdout/stderr/exitCode
611
+ 4. ✅ Auto cleanup temp directory
612
+
613
+ ---
614
+
615
+ ## Best Practices
616
+
617
+ ### DO ✅
618
+ - Luôn dùng \`mkdir -p $(dirname "...")\` trước mỗi file
619
+ - Sử dụng \`<<'EOF'\` để tránh variable expansion
620
+ - Ghi đè toàn bộ nội dung file
621
+ - Chỉ include files có thay đổi thực sự
622
+
623
+ ### DON'T ❌
624
+ - Không tạo file mà không tạo thư mục cha
625
+ - Không dùng \`<<EOF\` (thiếu quotes) nếu có \`$\` trong content
626
+ - Không include files không thay đổi
627
+ - Không dùng relative paths phức tạp`;
628
+
629
+ // Load system prompt on page load
630
+ document.getElementById('prompt-text').textContent = SYSTEM_PROMPT;
631
+
632
+ function toggleSystemPrompt() {
633
+ const content = document.getElementById('system-prompt-content');
634
+ const icon = document.getElementById('toggle-icon');
635
+ content.classList.toggle('open');
636
+ icon.classList.toggle('open');
637
+ }
638
+
639
+ function copySystemPrompt() {
640
+ const copyBtn = event.target.closest('.btn-copy');
641
+ const copyIcon = document.getElementById('copy-icon');
642
+ const copyText = document.getElementById('copy-text');
643
+
644
+ navigator.clipboard.writeText(SYSTEM_PROMPT).then(() => {
645
+ copyBtn.classList.add('copied');
646
+ copyIcon.textContent = '✓';
647
+ copyText.textContent = 'Copied!';
648
+
649
+ setTimeout(() => {
650
+ copyBtn.classList.remove('copied');
651
+ copyIcon.textContent = '📋';
652
+ copyText.textContent = 'Copy System Prompt';
653
+ }, 2000);
654
+ }).catch(err => {
655
+ alert('Failed to copy: ' + err.message);
656
+ });
657
+ }
658
+
659
+ // Check server status ONCE on page load
660
+ (async () => {
408
661
  try {
409
662
  const res = await fetch(`${API_BASE}/health`);
410
663
  if (res.ok) {
664
+ const data = await res.json();
411
665
  document.getElementById('status').textContent = '● Server Running';
412
666
  document.getElementById('status').style.background = '#10b981';
667
+ // Auto-show health check result
668
+ showResponse('health-response', data);
413
669
  }
414
670
  } catch {
415
671
  document.getElementById('status').textContent = '● Server Offline';
416
672
  document.getElementById('status').style.background = '#ef4444';
417
673
  }
418
- }, 5000);
674
+ })();
419
675
  </script>
420
676
  </body>
421
- </html>
677
+
678
+ </html>