import { showToastr } from './cwb_utils.js'; const { SillyTavern } = window; const GIT_REPO_OWNER = 'Wx-2025'; const GIT_REPO_NAME = 'ST-Amily2-Chat-Optimisation'; const EXTENSION_NAME = 'ST-Amily2-Chat-Optimisation'; const EXTENSION_FOLDER_PATH = `scripts/extensions/third-party/${EXTENSION_NAME}`; let currentVersion = '0.0.0'; let latestVersion = '0.0.0'; let changelogContent = ''; async function fetchRawFileFromGitHub(filePath) { const url = `https://raw.githubusercontent.com/${GIT_REPO_OWNER}/${GIT_REPO_NAME}/main/${filePath}`; const response = await fetch(url, { cache: 'no-cache' }); if (!response.ok) { throw new Error(`Failed to fetch ${filePath} from GitHub: ${response.statusText}`); } return response.text(); } function parseVersion(content) { try { return JSON.parse(content).version || '0.0.0'; } catch (error) { console.error(`[cwb_updater] Failed to parse version:`, error); return '0.0.0'; } } function compareVersions(v1, v2) { const parts1 = v1.split('.').map(Number); const parts2 = v2.split('.').map(Number); for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) { const p1 = parts1[i] || 0; const p2 = parts2[i] || 0; if (p1 > p2) return 1; if (p1 < p2) return -1; } return 0; } async function performUpdate() { const { getRequestHeaders } = SillyTavern.getContext().common; const { extension_types } = SillyTavern.getContext().extensions; showToastr('info', '正在开始更新主扩展...'); try { const response = await fetch('/api/extensions/update', { method: 'POST', headers: getRequestHeaders(), body: JSON.stringify({ extensionName: EXTENSION_NAME, global: extension_types[EXTENSION_NAME] === 'global', }), }); if (!response.ok) throw new Error(await response.text()); showToastr('success', '更新成功!将在3秒后刷新页面应用更改。'); setTimeout(() => location.reload(), 3000); } catch (error) { showToastr('error', `更新失败: ${error.message}`); } } async function showUpdateConfirmDialog() { const { POPUP_TYPE, callGenericPopup } = SillyTavern; try { changelogContent = await fetchRawFileFromGitHub('CHANGELOG.md'); } catch (error) { changelogContent = `发现新版本 ${latestVersion}!您想现在更新吗?`; } if ( await callGenericPopup(changelogContent, POPUP_TYPE.CONFIRM, { okButton: '立即更新', cancelButton: '稍后', wide: true, large: true, }) ) { await performUpdate(); } } export async function checkForUpdates(isManual = false, $panel) { if (!$panel) return; const $updateButton = $panel.find('#cwb-check-for-updates'); const $updateIndicator = $panel.find('.cwb-update-indicator'); if (isManual) { $updateButton.prop('disabled', true).html(' 检查中...'); } try { const localManifestText = await (await fetch(`/${EXTENSION_FOLDER_PATH}/manifest.json?t=${Date.now()}`)).text(); currentVersion = parseVersion(localManifestText); $panel.find('#cwb-current-version').text(currentVersion); const remoteManifestText = await fetchRawFileFromGitHub('manifest.json'); latestVersion = parseVersion(remoteManifestText); if (compareVersions(latestVersion, currentVersion) > 0) { $updateIndicator.show(); $updateButton .html(` 发现新版 ${latestVersion}!`) .off('click') .on('click', () => showUpdateConfirmDialog()); if (isManual) showToastr('success', `发现新版本 ${latestVersion}!点击按钮进行更新。`); } else { $updateIndicator.hide(); if (isManual) showToastr('info', '您当前已是最新版本。'); } } catch (error) { if (isManual) showToastr('error', `检查更新失败: ${error.message}`); } finally { if (isManual && compareVersions(latestVersion, currentVersion) <= 0) { $updateButton.prop('disabled', false).html(' 检查更新'); } } }