vg-coder-cli 1.0.14 → 1.0.16
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
|
@@ -363,6 +363,10 @@
|
|
|
363
363
|
<span id="analyze-copy-icon">📋</span>
|
|
364
364
|
<span id="analyze-copy-text">Copy to Clipboard</span>
|
|
365
365
|
</button>
|
|
366
|
+
<button class="btn btn-copy" onclick="copyAnalyzeAsFile()">
|
|
367
|
+
<span id="analyze-file-icon">📄</span>
|
|
368
|
+
<span id="analyze-file-text">Copy as File</span>
|
|
369
|
+
</button>
|
|
366
370
|
</div>
|
|
367
371
|
<div class="response" id="analyze-response"></div>
|
|
368
372
|
</div>
|
|
@@ -672,6 +676,75 @@ API sẽ:
|
|
|
672
676
|
}
|
|
673
677
|
}
|
|
674
678
|
|
|
679
|
+
async function copyAsFile(filename, content) {
|
|
680
|
+
const blob = new Blob([content], {
|
|
681
|
+
type: "application/octet-stream"
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
// ClipboardItem cần type key phải trùng blob.type
|
|
685
|
+
const item = new ClipboardItem(
|
|
686
|
+
{ [blob.type]: blob },
|
|
687
|
+
{
|
|
688
|
+
// Không phải chuẩn, nhưng Chrome hỗ trợ unofficial metadata
|
|
689
|
+
type: "application/octet-stream",
|
|
690
|
+
presentationStyle: "attachment",
|
|
691
|
+
name: filename
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
await navigator.clipboard.write([item]);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
async function copyAnalyzeAsFile() {
|
|
699
|
+
const copyBtn = event.target.closest('.btn-copy');
|
|
700
|
+
const copyIcon = document.getElementById('analyze-file-icon');
|
|
701
|
+
const copyText = document.getElementById('analyze-file-text');
|
|
702
|
+
|
|
703
|
+
if (!lastAnalyzeResult) {
|
|
704
|
+
// Fetch if not already analyzed
|
|
705
|
+
const path = document.getElementById('analyze-path').value;
|
|
706
|
+
showLoading(copyBtn, '<span id="analyze-file-icon">📄</span><span id="analyze-file-text">Copy as File</span>');
|
|
707
|
+
|
|
708
|
+
try {
|
|
709
|
+
const res = await fetch(`${API_BASE}/api/analyze`, {
|
|
710
|
+
method: 'POST',
|
|
711
|
+
headers: { 'Content-Type': 'application/json' },
|
|
712
|
+
body: JSON.stringify({ path })
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
if (res.ok) {
|
|
716
|
+
lastAnalyzeResult = await res.text();
|
|
717
|
+
} else {
|
|
718
|
+
showToast('❌ Lỗi analyze!', 'error');
|
|
719
|
+
resetButton(copyBtn);
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
} catch (err) {
|
|
723
|
+
showToast('❌ Lỗi: ' + err.message, 'error');
|
|
724
|
+
resetButton(copyBtn);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
resetButton(copyBtn);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
try {
|
|
731
|
+
await copyAsFile("project.txt", lastAnalyzeResult);
|
|
732
|
+
|
|
733
|
+
copyBtn.classList.add('copied');
|
|
734
|
+
copyIcon.textContent = '✓';
|
|
735
|
+
copyText.textContent = 'Copied!';
|
|
736
|
+
showToast('✅ Đã copy project.txt như file!', 'success');
|
|
737
|
+
|
|
738
|
+
setTimeout(() => {
|
|
739
|
+
copyBtn.classList.remove('copied');
|
|
740
|
+
copyIcon.textContent = '📄';
|
|
741
|
+
copyText.textContent = 'Copy as File';
|
|
742
|
+
}, 2000);
|
|
743
|
+
} catch (err) {
|
|
744
|
+
showToast('❌ Lỗi copy: ' + err.message, 'error');
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
675
748
|
async function testExecute() {
|
|
676
749
|
const btn = event.target.closest('.btn');
|
|
677
750
|
const bash = document.getElementById('execute-bash').value;
|