(path, filename)
| 4499 | |
| 4500 | } catch (error) { |
| 4501 | CarrotDebug.error('Failed to scan existing lorebooks:', error); |
| 4502 | return 0; |
| 4503 | } |
| 4504 | |
| 4505 | // Execute the actual installation |
| 4506 | } |
| 4507 | async function executeInstall(path, filename) { |
| 4508 | const progressEl = document.getElementById('carrot-install-progress'); |
| 4509 | const progressFillEl = document.getElementById('carrot-progress-fill'); |
| 4510 | const progressTextEl = document.getElementById('carrot-progress-text'); |
| 4511 | const installBtn = document.getElementById('carrot-install-btn'); |
| 4512 | const cancelBtn = document.getElementById('carrot-cancel-btn'); |
| 4513 | |
| 4514 | try { |
| 4515 | // Show progress |
| 4516 | progressEl.style.display = 'block'; |
| 4517 | installBtn.disabled = true; |
| 4518 | cancelBtn.disabled = true; |
| 4519 | |
| 4520 | // Step 1: Download |
| 4521 | progressTextEl.textContent = 'Downloading pack from GitHub...'; |
| 4522 | progressFillEl.style.width = '25%'; |
| 4523 | |
| 4524 | const downloadUrl = await githubBrowser.getDownloadUrl(path); |
| 4525 | const response = await fetch(downloadUrl); |
| 4526 | |
| 4527 | if (!response.ok) { |
| 4528 | throw new Error(`HTTP ${response.status}: ${response.statusText}`); |
| 4529 | } |
| 4530 | |
| 4531 | // Step 2: Parse |
| 4532 | progressTextEl.textContent = 'Processing pack data...'; |
| 4533 | progressFillEl.style.width = '50%'; |
| 4534 | |
| 4535 | const data = await response.json(); |
| 4536 | const entries = data.entries || []; |
| 4537 | |
| 4538 | // Step 3: Install |
| 4539 | // Delegate to installPackNative(), which uses ST's actual /api/worldinfo/import |
| 4540 | // contract (a multipart file upload) instead of a raw JSON POST that endpoint rejects. |
| 4541 | progressTextEl.textContent = 'Installing to SillyTavern lorebooks...'; |
| 4542 | progressFillEl.style.width = '75%'; |
| 4543 | |
| 4544 | const cleanName = filename.replace('.json', ''); |
| 4545 | const installed = await installPackNative(downloadUrl, filename); |
| 4546 | |
| 4547 | if (!installed) { |
| 4548 | throw new Error('Failed to install lorebook'); |
| 4549 | } |
| 4550 | |
| 4551 | // Step 4: Track installation with SHA |
| 4552 | const currentItem = githubBrowser.currentItems.find(item => item.path === path); |
| 4553 | if (currentItem) { |
| 4554 | githubBrowser.trackPackInstallation(filename, currentItem.sha, currentItem.size); |
| 4555 | CarrotDebug.repo(`✅ Tracked installation: ${filename} (SHA: ${currentItem.sha})`); |
| 4556 | } |
| 4557 | |
| 4558 | progressTextEl.textContent = 'Installation complete!'; |
no test coverage detected