diff --git a/apps/app-frontend/src/components/ui/settings/DefaultInstanceSettings.vue b/apps/app-frontend/src/components/ui/settings/DefaultInstanceSettings.vue index 68c5089..1f8f28b 100644 --- a/apps/app-frontend/src/components/ui/settings/DefaultInstanceSettings.vue +++ b/apps/app-frontend/src/components/ui/settings/DefaultInstanceSettings.vue @@ -6,6 +6,8 @@ import { ref, watch } from 'vue' import { get, set } from '@/helpers/settings.ts' import CrashAnalysisAISettings from './CrashAnalysisAISettings.vue' +import LogShareSettings from './LogShareSettings.vue' +import SharedLogsSettings from './SharedLogsSettings.vue' import SettingsRow from './SettingsRow.vue' import SettingsSection from './SettingsSection.vue' @@ -391,5 +393,7 @@ watch( + + diff --git a/apps/app-frontend/src/components/ui/settings/LogShareSettings.vue b/apps/app-frontend/src/components/ui/settings/LogShareSettings.vue new file mode 100644 index 0000000..ad3b5a2 --- /dev/null +++ b/apps/app-frontend/src/components/ui/settings/LogShareSettings.vue @@ -0,0 +1,354 @@ + + + + + + {{ formatMessage(messages.shareProvider) }} + {{ formatMessage(messages.shareProviderDescription) }} + + + + + + {{ formatMessage(messages.aiSource) }} + {{ formatMessage(messages.aiSourceDescription) }} + + + + + + + {{ formatMessage(messages.enabled) }} + {{ formatMessage(messages.enabledDescription) }} + + + + + + + {{ formatMessage(messages.provider) }} + + + + + + {{ formatMessage(messages.model) }} + + + + + + + {{ formatMessage(messages.noProviders) }} + + + + {{ formatMessage(messages.autoUpload) }} + {{ formatMessage(messages.autoUploadDescription) }} + + + + + + {{ formatMessage(messages.multiFile) }} + {{ formatMessage(messages.multiFileDescription) }} + + + + + + {{ formatMessage(messages.noStorage) }} + {{ formatMessage(messages.noStorageDescription) }} + + + + + + {{ formatMessage(messages.showProgress) }} + {{ formatMessage(messages.showProgressDescription) }} + + + + + + diff --git a/apps/app-frontend/src/components/ui/settings/SharedLogsSettings.vue b/apps/app-frontend/src/components/ui/settings/SharedLogsSettings.vue new file mode 100644 index 0000000..62f17a3 --- /dev/null +++ b/apps/app-frontend/src/components/ui/settings/SharedLogsSettings.vue @@ -0,0 +1,129 @@ + + + + + + + + … + + {{ formatMessage(messages.empty) }} + + + + + {{ log.url || log.id }} + + + {{ log.provider }} + + · {{ formatMessage(messages.truncated) }} + + · {{ log.instance_name }} + · {{ formatDate(log.created_at) }} + + {{ + deletingId === log.id + ? formatMessage(messages.deleting) + : formatMessage(messages.delete) + }} + + + + + + + + diff --git a/apps/app-frontend/src/helpers/logs.js b/apps/app-frontend/src/helpers/logs.js index 7ed4794..91a1840 100644 --- a/apps/app-frontend/src/helpers/logs.js +++ b/apps/app-frontend/src/helpers/logs.js @@ -95,6 +95,50 @@ export async function undo_added_mod(instanceId, filename, expectedHash) { return await invoke('plugin:logs|logs_undo_added_mod', { instanceId, filename, expectedHash }) } +export async function get_log_share_settings() { + return await invoke('plugin:logs|logs_get_log_share_settings') +} + +export async function update_log_share_settings(settings) { + return await invoke('plugin:logs|logs_update_log_share_settings', { settings }) +} + +export async function logshare_upload_crash(instanceId) { + return await invoke('plugin:logs|logs_logshare_upload_crash', { instanceId }) +} + +export async function logshare_get_insights(id) { + return await invoke('plugin:logs|logs_logshare_get_insights', { id }) +} + +export async function logshare_analyse_crash_direct(instanceId) { + return await invoke('plugin:logs|logs_logshare_analyse_crash_direct', { instanceId }) +} + +export async function logshare_ai_analyze_stored(instanceId, id) { + return await invoke('plugin:logs|logs_logshare_ai_analyze_stored', { instanceId, id }) +} + +export async function logshare_ai_analyze_direct(instanceId) { + return await invoke('plugin:logs|logs_logshare_ai_analyze_direct', { instanceId }) +} + +export async function logshare_delete(id, token) { + return await invoke('plugin:logs|logs_logshare_delete', { id, token }) +} + +export async function list_shared_logs() { + return await invoke('plugin:logs|logs_list_shared_logs') +} + +export async function record_shared_log(log) { + return await invoke('plugin:logs|logs_record_shared_log', { log }) +} + +export async function delete_shared_log(id, token) { + return await invoke('plugin:logs|logs_delete_shared_log', { id, token }) +} + /// Export the censored files and local analysis from an instance's latest run. export async function export_crash_context(instanceId, instanceName) { const timestamp = new Date().toISOString().replace(/[:.]/g, '-') diff --git a/apps/app-frontend/src/locales/en-US/index.json b/apps/app-frontend/src/locales/en-US/index.json index 7d9d32a..741cadd 100644 --- a/apps/app-frontend/src/locales/en-US/index.json +++ b/apps/app-frontend/src/locales/en-US/index.json @@ -11600,4 +11600,29 @@ "app.library.context-menu.unpin-instance": {"message": "Unpin instance"}, "app.library.group.new": {"message": "New group"}, "app.library.selection.new-group": {"message": "New group"}, - "app.library.selection.remove-from-group": {"message": "Remove from group"}} + "app.library.selection.remove-from-group": {"message": "Remove from group"}, + "app.log-share.settings.title": {"message": "Log sharing & AI analysis"}, + "app.log-share.settings.description": {"message": "Share crash diagnostics with LogShare for a structured summary and optional AI analysis. LogShare is preferred; mclo.gs is used as a fallback."}, + "app.log-share.settings.share-provider": {"message": "Log sharing service"}, + "app.log-share.settings.share-provider-description": {"message": "Where the diagnostic link is uploaded when you share it."}, + "app.log-share.settings.ai-source": {"message": "AI analysis source"}, + "app.log-share.settings.ai-source-logshare": {"message": "LogShare AI"}, + "app.log-share.settings.ai-source-custom": {"message": "Custom AI provider"}, + "app.log-share.settings.ai-source-description": {"message": "Both sources send a sanitized and shortened crash context. AI output may be inaccurate."}, + "app.log-share.settings.auto-upload": {"message": "Upload to get a structured summary automatically"}, + "app.log-share.settings.auto-upload-description": {"message": "Only effective in LogShare AI mode."}, + "app.log-share.settings.multi-file": {"message": "Multi-file upload"}, + "app.log-share.settings.multi-file-description": {"message": "Upload latest.log, crash reports, hs_err and launcher logs together."}, + "app.log-share.settings.no-storage": {"message": "Analyze without storing logs"}, + "app.log-share.settings.no-storage-description": {"message": "Submit content directly for analysis and skip the stored upload. Disables the automatic summary."}, + "app.log-share.settings.show-progress": {"message": "Show AI analysis progress"}, + "app.log-share.settings.show-progress-description": {"message": "Display thinking, tool and limit status while LogShare AI is working."}, + "app.log-share.shared-logs.title": {"message": "Shared logs"}, + "app.log-share.shared-logs.description": {"message": "Every diagnostic you have shared is listed here. Delete an entry to remove it from your history and request its removal from the sharing service."}, + "app.log-share.shared-logs.empty": {"message": "No shared logs yet."}, + "app.log-share.shared-logs.delete": {"message": "Delete"}, + "app.log-share.shared-logs.deleting": {"message": "Deleting…"}, + "app.log-share.shared-logs.deleted": {"message": "Shared log removed."}, + "app.log-share.shared-logs.delete-failed": {"message": "Failed to delete the shared log."}, + "app.log-share.shared-logs.truncated": {"message": "Truncated"} +} diff --git a/apps/app-frontend/src/locales/zh-CN/index.json b/apps/app-frontend/src/locales/zh-CN/index.json index 2384d80..c867159 100644 --- a/apps/app-frontend/src/locales/zh-CN/index.json +++ b/apps/app-frontend/src/locales/zh-CN/index.json @@ -11431,4 +11431,29 @@ "app.library.context-menu.unpin-instance": {"message": "取消置顶"}, "app.library.group.new": {"message": "新建分组"}, "app.library.selection.new-group": {"message": "新建分组"}, - "app.library.selection.remove-from-group": {"message": "移出分组"}} + "app.library.selection.remove-from-group": {"message": "移出分组"}, + "app.log-share.settings.title": {"message": "日志分享与 AI 分析"}, + "app.log-share.settings.description": {"message": "将崩溃诊断分享到 LogShare,获取结构化摘要与可选的 AI 分析。优先使用 LogShare,不可用时回退到 mclo.gs。"}, + "app.log-share.settings.share-provider": {"message": "日志分享服务"}, + "app.log-share.settings.share-provider-description": {"message": "分享诊断链接时上传到的目标服务。"}, + "app.log-share.settings.ai-source": {"message": "AI 分析来源"}, + "app.log-share.settings.ai-source-logshare": {"message": "LogShare AI"}, + "app.log-share.settings.ai-source-custom": {"message": "自定义 AI 服务商"}, + "app.log-share.settings.ai-source-description": {"message": "LogShare AI 在云端分析;自定义则使用下方配置的服务商。"}, + "app.log-share.settings.auto-upload": {"message": "自动上传以获取结构化摘要"}, + "app.log-share.settings.auto-upload-description": {"message": "仅在 LogShare 模式下生效。"}, + "app.log-share.settings.multi-file": {"message": "多文件上传"}, + "app.log-share.settings.multi-file-description": {"message": "同时上传 latest.log、崩溃报告、hs_err 以及启动器日志。"}, + "app.log-share.settings.no-storage": {"message": "不落盘直接分析"}, + "app.log-share.settings.no-storage-description": {"message": "直接提交内容进行分析并跳过存储上传。会关闭自动摘要。"}, + "app.log-share.settings.show-progress": {"message": "显示 AI 分析进度"}, + "app.log-share.settings.show-progress-description": {"message": "展示 LogAgent 运行期间的思考、工具及上限状态。"}, + "app.log-share.shared-logs.title": {"message": "已分享日志"}, + "app.log-share.shared-logs.description": {"message": "你分享过的所有诊断都记录在这里。删除条目会将其从记录中移除,并向分享服务请求删除。"}, + "app.log-share.shared-logs.empty": {"message": "暂无已分享的日志。"}, + "app.log-share.shared-logs.delete": {"message": "删除"}, + "app.log-share.shared-logs.deleting": {"message": "删除中…"}, + "app.log-share.shared-logs.deleted": {"message": "已删除共享日志。"}, + "app.log-share.shared-logs.delete-failed": {"message": "删除已分享日志失败。"}, + "app.log-share.shared-logs.truncated": {"message": "已截断"} +} diff --git a/scripts/axolotl/i18n-check.mjs b/scripts/axolotl/i18n-check.mjs index 5625955..9559f96 100644 --- a/scripts/axolotl/i18n-check.mjs +++ b/scripts/axolotl/i18n-check.mjs @@ -30,6 +30,7 @@ const allowedUntranslatedMessages = new Set([ 'Cleanroom', 'LiteLoader', 'LogShare.CN', + 'LogShare AI', 'NeoForge', 'OptiFine', 'Quilt',
+ {{ formatMessage(messages.noProviders) }} +
…
+ {{ formatMessage(messages.empty) }} +