aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/.github
diff options
context:
space:
mode:
author简律纯 <i@jyunko.cn>2026-01-18 12:24:29 +0800
committerGitHub <noreply@github.com>2026-01-18 12:24:29 +0800
commitfd00ac6878b2cee9337b9e92d0c990ecdce9a346 (patch)
treebb5540f763dc0061877c9d9ac53747d79193eecc /.github
parentad36e0ce82770f9b3509ddb1cf96bc3422969806 (diff)
parent6d82ab2275130f3bafdb7ec664297eb700321526 (diff)
downloadDropOut-fd00ac6878b2cee9337b9e92d0c990ecdce9a346.tar.gz
DropOut-fd00ac6878b2cee9337b9e92d0c990ecdce9a346.zip
Merge pull request #58 from HsiangNianian/main
Diffstat (limited to '.github')
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml211
-rw-r--r--.github/ISSUE_TEMPLATE/cn-bug-report.yml211
-rw-r--r--.github/ISSUE_TEMPLATE/cn-feature-request.yml118
-rw-r--r--.github/ISSUE_TEMPLATE/cn-question.yml87
-rw-r--r--.github/ISSUE_TEMPLATE/config.yml11
-rw-r--r--.github/ISSUE_TEMPLATE/feature_request.yml118
-rw-r--r--.github/ISSUE_TEMPLATE/question.yml87
-rw-r--r--.github/PULL_REQUEST_TEMPLATE/cn-pull_request_template.md127
-rw-r--r--.github/PULL_REQUEST_TEMPLATE/en-pull_request_template.md127
-rw-r--r--.github/agents/commit.agent.md260
-rw-r--r--.github/copilot-instructions.md289
-rw-r--r--.github/instructions/commit.instructions.md38
-rw-r--r--.github/references/git/conventional-commit.md153
-rw-r--r--.github/workflows/check.yml4
-rw-r--r--.github/workflows/issue-checkbox-checker.yml104
-rw-r--r--.github/workflows/prek.yml60
-rw-r--r--.github/workflows/stale.yml92
-rw-r--r--.github/workflows/test.yml72
18 files changed, 2165 insertions, 4 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..063bbb7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,211 @@
+name: Bug Report
+description: Report a bug or issue with DropOut Minecraft Launcher
+title: "[Bug]: "
+labels: ["bug", "needs-triage"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for taking the time to report a bug! Please fill out the form below to help us understand and fix the issue.
+
+ - type: checkboxes
+ id: prerequisites
+ attributes:
+ label: Prerequisites
+ description: Please confirm you have completed the following before submitting. Issues that check "I have not read carefully" or fail to meet required items may be closed immediately.
+ options:
+ - label: I understand that Issues are for reporting and solving problems, not for comments or complaints. I will provide as much information as possible to help resolve the issue.
+ required: false
+ - label: I have not read carefully and just clicked through everything, believing this won't affect issue handling.
+ required: false
+ - label: I have filled in a short and clear title so that developers can quickly identify the issue when browsing the Issue list, rather than "a suggestion" or "stuck" etc.
+ required: false
+ - label: I have searched existing issues to ensure this is not a duplicate
+ required: false
+ - label: I am using the latest version of DropOut
+ required: false
+ - label: I have read the README and documentation
+ required: false
+
+ - type: input
+ id: version
+ attributes:
+ label: DropOut Version
+ description: What version of DropOut are you using?
+ placeholder: "e.g., 0.1.23"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: os
+ attributes:
+ label: Operating System
+ description: Which operating system are you using?
+ options:
+ - Windows 11
+ - Windows 10
+ - Windows 8,8.1
+ - Windows 7
+ - macOS (Apple Silicon)
+ - macOS (Intel)
+ - Linux (Debian/Ubuntu)
+ - Linux (Arch)
+ - Linux (Fedora/RHEL)
+ - Other Linux
+ validations:
+ required: true
+
+ - type: input
+ id: os-version
+ attributes:
+ label: OS Version
+ description: Specific version of your operating system
+ placeholder: "e.g., Windows 11 23H2, macOS 14.2, Ubuntu 22.04"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: minecraft-version
+ attributes:
+ label: Minecraft Version
+ description: Which Minecraft version are you trying to launch?
+ options:
+ - "1.21.x"
+ - "1.20.x"
+ - "1.19.x"
+ - "1.18.x"
+ - "1.17.x"
+ - "1.16.x"
+ - "1.12.x"
+ - Other (specify in description)
+ validations:
+ required: true
+
+ - type: dropdown
+ id: mod-loader
+ attributes:
+ label: Mod Loader
+ description: Are you using a mod loader?
+ options:
+ - None (Vanilla)
+ - Fabric
+ - Forge
+ - Not applicable
+ validations:
+ required: true
+
+ - type: input
+ id: java-version
+ attributes:
+ label: Java Version
+ description: Which Java version are you using?
+ placeholder: "e.g., Java 21.0.1, Java 17.0.9, Java 8u381"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: java-source
+ attributes:
+ label: Java Source
+ description: Where did you get Java from?
+ options:
+ - Auto-detected by DropOut
+ - Downloaded via DropOut
+ - Manually installed (Oracle)
+ - Manually installed (Sdkman)
+ - Manually installed (Homebrew)
+ - Manually installed (Chocolatey)
+ - Manually installed (Other)
+ - Unknown
+ validations:
+ required: false
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Bug Description
+ description: A clear and concise description of what the bug is
+ placeholder: Describe the issue you're experiencing...
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Steps to Reproduce
+ description: Steps to reproduce the behavior
+ placeholder: |
+ 1. Go to '...'
+ 2. Click on '...'
+ 3. Scroll down to '...'
+ 4. See error
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ description: What did you expect to happen?
+ placeholder: Describe what you expected to happen...
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual Behavior
+ description: What actually happened?
+ placeholder: Describe what actually happened...
+ validations:
+ required: true
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Logs and Error Messages
+ description: |
+ Please upload log files from the DropOut launcher terminal, then paste the log link here.
+
+ **How to upload logs:**
+ 1. Open the terminal in DropOut launcher
+ 2. Use the built-in log upload feature
+ 3. Copy the generated log link and paste it below
+
+ If automatic upload is unavailable, you can manually retrieve logs from:
+ - **macOS**: `$HOME/Library/Application Support/com.dropout.launcher/logs`
+ - **Linux**: `$HOME/.local/share/com.dropout.launcher`
+ placeholder: |
+ Paste log link or log content...
+ validations:
+ required: false
+
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: Screenshots or Screen Recordings
+ description: |
+ If applicable, add screenshots or screen recordings to help explain your problem.
+
+ **Screenshot Requirements:**
+ - Use native screenshot tools (Windows: `Win+Shift+S`, macOS: `Cmd+Shift+4`, Linux: `gnome-screenshot`/`spectacle`)
+ - DO NOT use QQ/WeChat/Discord screenshot tools as they may alter resolution and aspect ratio
+ - Provide unobstructed original images, avoid window borders or overlays
+ - For game-related issues, capture the actual game window
+ - Keep the original resolution and DPI
+
+ You can compress large files before uploading.
+ placeholder: Drag and drop images here or paste image URLs
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Add any other context about the problem here
+ placeholder: Any additional information that might be helpful...
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/cn-bug-report.yml b/.github/ISSUE_TEMPLATE/cn-bug-report.yml
new file mode 100644
index 0000000..a128e28
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/cn-bug-report.yml
@@ -0,0 +1,211 @@
+name: Bug 反馈(中文)
+description: 报告 DropOut Minecraft 启动器的错误或问题
+title: "[Bug]: "
+labels: ["bug", "needs-triage"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ 感谢您花时间报告 Bug!请填写以下表单以帮助我们理解和修复问题。
+
+ - type: checkboxes
+ id: prerequisites
+ attributes:
+ label: 前置确认
+ description: 请确认自己完成了下列项目之后再进行勾选,若未完成必选项或勾选了"我未仔细阅读"选项将视为自愿接受被直接关闭 Issue
+ options:
+ - label: 我理解 Issue 是用于反馈和解决问题的,而非吐槽评论区,将尽可能提供更多信息帮助问题解决
+ required: false
+ - label: 我未仔细阅读这些内容,只是一键已读所有内容,并相信这不会影响问题的处理
+ required: false
+ - label: 我填写了简短且清晰明确的标题,以便开发者在翻阅 Issue 列表时能快速确定大致问题,而不是"一个建议"、"卡住了"等
+ required: false
+ - label: 我已搜索现有 Issue,确认这不是重复问题
+ required: false
+ - label: 我正在使用最新版本的 DropOut
+ required: false
+ - label: 我已阅读 README 和文档
+ required: false
+
+ - type: input
+ id: version
+ attributes:
+ label: DropOut 版本
+ description: 您正在使用的 DropOut 版本是?
+ placeholder: "例如:0.1.23"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: os
+ attributes:
+ label: 操作系统
+ description: 您使用的操作系统是?
+ options:
+ - Windows 11
+ - Windows 10
+ - Windows 8/8.1
+ - Windows 7
+ - macOS (Apple Silicon)
+ - macOS (Intel)
+ - Linux (Debian/Ubuntu)
+ - Linux (Arch)
+ - Linux (Fedora/RHEL)
+ - 其他 Linux
+ validations:
+ required: true
+
+ - type: input
+ id: os-version
+ attributes:
+ label: 操作系统版本
+ description: 操作系统的具体版本号
+ placeholder: "例如:Windows 11 23H2, macOS 14.2, Ubuntu 22.04"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: minecraft-version
+ attributes:
+ label: Minecraft 版本
+ description: 您尝试启动的 Minecraft 版本是?
+ options:
+ - "1.21.x"
+ - "1.20.x"
+ - "1.19.x"
+ - "1.18.x"
+ - "1.17.x"
+ - "1.16.x"
+ - "1.12.x"
+ - 其他(请在描述中说明)
+ validations:
+ required: true
+
+ - type: dropdown
+ id: mod-loader
+ attributes:
+ label: Mod 加载器
+ description: 您是否使用了 Mod 加载器?
+ options:
+ - 无(原版)
+ - Fabric
+ - Forge
+ - 不适用
+ validations:
+ required: true
+
+ - type: input
+ id: java-version
+ attributes:
+ label: Java 版本
+ description: 您使用的 Java 版本是?
+ placeholder: "例如:Java 21.0.1, Java 17.0.9, Java 8u381"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: java-source
+ attributes:
+ label: Java 来源
+ description: 您的 Java 来自哪里?
+ options:
+ - DropOut 自动检测
+ - 通过 DropOut 下载
+ - 手动安装 (Oracle)
+ - 手动安装 (Sdkman)
+ - 手动安装 (Homebrew)
+ - 手动安装 (Chocolatey)
+ - 手动安装 (其他)
+ - 未知
+ validations:
+ required: false
+
+ - type: textarea
+ id: description
+ attributes:
+ label: 问题描述
+ description: 清晰简洁地描述这个 Bug 是什么
+ placeholder: 描述您遇到的问题...
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: 复现步骤
+ description: 复现该问题的步骤
+ placeholder: |
+ 1. 打开 '...'
+ 2. 点击 '...'
+ 3. 滚动到 '...'
+ 4. 出现错误
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: 预期行为
+ description: 您期望发生什么?
+ placeholder: 描述您期望发生的事情...
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: 实际行为
+ description: 实际发生了什么?
+ placeholder: 描述实际发生的事情...
+ validations:
+ required: true
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: 日志和错误信息
+ description: |
+ 请从 DropOut 启动器终端上传日志文件,然后在此粘贴日志链接。
+
+ **如何上传日志:**
+ 1. 在 DropOut 启动器中打开终端
+ 2. 使用内置的日志上传功能
+ 3. 复制生成的日志链接并粘贴到下方
+
+ 如果无法使用自动上传,可以手动从以下位置获取日志:
+ - **macOS**: `$HOME/Library/Application Support/com.dropout.launcher/logs`
+ - **Linux**: `$HOME/.local/share/com.dropout.launcher`
+ placeholder: |
+ 粘贴日志链接或日志内容...
+ validations:
+ required: false
+
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: 截图或录屏
+ description: |
+ 如果适用,请添加截图或录屏以帮助说明您的问题。
+
+ **截图要求:**
+ - 使用系统自带截图工具(Windows: `Win+Shift+S`, macOS: `Cmd+Shift+4`, Linux: `gnome-screenshot`/`spectacle`)
+ - 不要使用 QQ/微信/Discord 截图工具,它们可能改变分辨率和纵横比
+ - 提供无遮挡的原始图片,避免窗口边框或覆盖层
+ - 对于游戏问题,请捕获实际游戏窗口
+ - 保持原始分辨率和 DPI
+
+ 可以在上传前压缩大文件。
+ placeholder: 拖放图片到这里或粘贴图片 URL
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: 其他信息
+ description: 在此添加关于该问题的任何其他信息
+ placeholder: 任何可能有帮助的额外信息...
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/cn-feature-request.yml b/.github/ISSUE_TEMPLATE/cn-feature-request.yml
new file mode 100644
index 0000000..366a533
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/cn-feature-request.yml
@@ -0,0 +1,118 @@
+name: 功能请求(中文)
+description: 为 DropOut 提出新功能或改进建议
+title: "[Feature]: "
+labels: ["enhancement", "needs-triage"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ 感谢您提出新功能建议!请填写以下表单以帮助我们理解您的需求。
+
+ - type: checkboxes
+ id: prerequisites
+ attributes:
+ label: 前置确认
+ description: 请确认自己完成了下列项目之后再进行勾选,若勾选了"我未仔细阅读"选项将视为自愿接受被直接关闭 Issue
+ options:
+ - label: 我理解 Issue 是用于反馈和解决问题的,而非吐槽评论区,将尽可能提供更多信息
+ required: false
+ - label: 我未仔细阅读这些内容,只是一键已读所有内容,并相信这不会影响问题的处理
+ required: false
+ - label: 我已搜索现有 Issue,确认这不是重复的功能请求
+ required: false
+ - label: 我已查看 README 中的 Roadmap
+ required: false
+ - label: 这个功能将使多个用户受益,而不仅仅是我自己
+ required: false
+
+ - type: dropdown
+ id: feature-type
+ attributes:
+ label: 功能类型
+ description: 您请求的是哪种类型的功能?
+ options:
+ - UI/UX 改进
+ - 游戏管理
+ - Mod 加载器支持
+ - 账户管理
+ - Java 管理
+ - 性能优化
+ - 新平台支持
+ - 文档
+ - 其他
+ validations:
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: 问题陈述
+ description: 您的功能请求是否与某个问题相关?请描述。
+ placeholder: "我总是对...感到困扰"
+ validations:
+ required: true
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: 建议的解决方案
+ description: 描述您希望看到的解决方案
+ placeholder: 清晰简洁地描述您希望发生的事情...
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: 替代方案
+ description: 描述您考虑过的任何替代解决方案或功能
+ placeholder: 是否有其他方法可以解决这个问题?
+ validations:
+ required: false
+
+ - type: textarea
+ id: examples
+ attributes:
+ label: 示例和参考
+ description: |
+ 提供其他启动器或应用程序实现类似功能的示例
+ placeholder: |
+ - MultiMC 通过...实现
+ - Prism Launcher 有类似功能...
+ - 可以像 [示例链接] 这样工作...
+ validations:
+ required: false
+
+ - type: dropdown
+ id: priority
+ attributes:
+ label: 优先级
+ description: 这个功能对您有多重要?
+ options:
+ - 关键(阻碍正常使用)
+ - 高(显著改善体验)
+ - 中(锦上添花)
+ - 低(小便利)
+ validations:
+ required: true
+
+ - type: checkboxes
+ id: contribution
+ attributes:
+ label: 贡献意愿
+ description: 您是否愿意为这个功能做出贡献?
+ options:
+ - label: 我愿意实现这个功能
+ - label: 我愿意帮助测试这个功能
+ - label: 我可以提供设计草图或规范
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: 其他信息
+ description: 在此添加关于功能请求的任何其他信息、草图或截图
+ placeholder: 任何可能有帮助的额外信息...
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/cn-question.yml b/.github/ISSUE_TEMPLATE/cn-question.yml
new file mode 100644
index 0000000..b7422e8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/cn-question.yml
@@ -0,0 +1,87 @@
+name: 问题咨询(中文)
+description: 询问关于使用 DropOut 的问题
+title: "[Question]: "
+labels: ["question"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ 有关于使用 DropOut 的问题吗?请填写以下表单。
+
+ **注意:** 如果是 Bug 报告,请使用 Bug 反馈模板。
+
+ - type: checkboxes
+ id: prerequisites
+ attributes:
+ label: 前置确认
+ description: 请确认自己完成了下列项目之后再进行勾选,若勾选了"我未仔细阅读"选项将视为自愿接受被直接关闭 Issue
+ options:
+ - label: 我理解 Issue 是用于提问和获取帮助的,而非吐槽评论区
+ required: false
+ - label: 我未仔细阅读这些内容,只是一键已读所有内容,并相信这不会影响问题的处理
+ required: false
+ - label: 我已搜索现有 Issue,查看是否有人已经回答了我的问题
+ required: false
+ - label: 我已阅读 README 和文档
+ required: false
+
+ - type: dropdown
+ id: category
+ attributes:
+ label: 问题类别
+ description: 您的问题是关于什么的?
+ options:
+ - 安装和设置
+ - 账户和认证
+ - Minecraft 版本管理
+ - Mod 加载器(Fabric/Forge)
+ - Java 安装和配置
+ - 游戏启动问题
+ - 设置和配置
+ - 从源代码构建
+ - 为项目做贡献
+ - 其他
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: 您的问题
+ description: 请详细描述您的问题
+ placeholder: 您想了解什么?
+ validations:
+ required: true
+
+ - type: input
+ id: version
+ attributes:
+ label: DropOut 版本(如果适用)
+ description: 您正在使用的 DropOut 版本是?
+ placeholder: "例如:0.1.23"
+ validations:
+ required: false
+
+ - type: dropdown
+ id: os
+ attributes:
+ label: 操作系统(如果适用)
+ description: 您使用的操作系统是?
+ options:
+ - Windows
+ - macOS
+ - Linux
+ - 不适用
+ validations:
+ required: false
+
+ - type: textarea
+ id: context
+ attributes:
+ label: 其他信息
+ description: 添加任何其他可能帮助我们回答您问题的上下文、截图或信息
+ placeholder: 任何额外的细节...
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..b2dbc20
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,11 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Documentation
+ url: https://dropout.hydroroll.team
+ about: Read the project documentation and guides
+ - name: Discussions
+ url: https://github.com/HsiangNianian/DropOut/discussions
+ about: Ask questions and discuss ideas with the community
+ - name: Releases
+ url: https://github.com/HsiangNianian/DropOut/releases
+ about: Download the latest version or view changelog
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..38cb216
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,118 @@
+name: Feature Request
+description: Suggest a new feature or enhancement for DropOut
+title: "[Feature]: "
+labels: ["enhancement", "needs-triage"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for suggesting a new feature! Please fill out the form below to help us understand your request.
+
+ - type: checkboxes
+ id: prerequisites
+ attributes:
+ label: Prerequisites
+ description: Please confirm you have completed the following before submitting. Issues that check "I have not read carefully" may be closed immediately.
+ options:
+ - label: I understand that Issues are for feedback and problem-solving, not for complaints. I will provide as much information as possible.
+ required: false
+ - label: I have not read carefully and just clicked through everything, believing this won't affect issue handling.
+ required: false
+ - label: I have searched existing issues to ensure this is not a duplicate
+ required: false
+ - label: I have checked the roadmap in the README
+ required: false
+ - label: This feature would benefit multiple users, not just myself
+ required: false
+
+ - type: dropdown
+ id: feature-type
+ attributes:
+ label: Feature Type
+ description: What type of feature are you requesting?
+ options:
+ - UI/UX Enhancement
+ - Game Management
+ - Mod Loader Support
+ - Account Management
+ - Java Management
+ - Performance Improvement
+ - New Platform Support
+ - Documentation
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem Statement
+ description: Is your feature request related to a problem? Please describe.
+ placeholder: "I'm always frustrated when..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: Proposed Solution
+ description: Describe the solution you'd like to see
+ placeholder: A clear and concise description of what you want to happen...
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternative Solutions
+ description: Describe any alternative solutions or features you've considered
+ placeholder: Are there other ways to solve this problem?
+ validations:
+ required: false
+
+ - type: textarea
+ id: examples
+ attributes:
+ label: Examples and References
+ description: |
+ Provide examples from other launchers or applications that implement similar features
+ placeholder: |
+ - MultiMC does this by...
+ - Prism Launcher has a similar feature...
+ - This could work like [example link]...
+ validations:
+ required: false
+
+ - type: dropdown
+ id: priority
+ attributes:
+ label: Priority
+ description: How important is this feature to you?
+ options:
+ - Critical (blocks normal usage)
+ - High (significantly improves experience)
+ - Medium (nice to have)
+ - Low (minor convenience)
+ validations:
+ required: true
+
+ - type: checkboxes
+ id: contribution
+ attributes:
+ label: Contribution
+ description: Would you be willing to contribute to this feature?
+ options:
+ - label: I would be willing to implement this feature
+ - label: I would be willing to help test this feature
+ - label: I can provide design mockups or specifications
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Add any other context, mockups, or screenshots about the feature request here
+ placeholder: Any additional information that might be helpful...
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
new file mode 100644
index 0000000..ac170ab
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.yml
@@ -0,0 +1,87 @@
+name: Question
+description: Ask a question about using DropOut
+title: "[Question]: "
+labels: ["question"]
+assignees: []
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Have a question about using DropOut? Please fill out the form below.
+
+ **Note:** For bug reports, please use the Bug Report template instead.
+
+ - type: checkboxes
+ id: prerequisites
+ attributes:
+ label: Prerequisites
+ description: Please confirm you have completed the following before submitting. Issues that check "I have not read carefully" may be closed immediately.
+ options:
+ - label: I understand that Issues are for asking questions and getting help, not for complaints.
+ required: false
+ - label: I have not read carefully and just clicked through everything, believing this won't affect issue handling.
+ required: false
+ - label: I have searched existing issues to see if my question has been answered
+ required: false
+ - label: I have read the README and documentation
+ required: false
+
+ - type: dropdown
+ id: category
+ attributes:
+ label: Question Category
+ description: What is your question about?
+ options:
+ - Installation and Setup
+ - Account and Authentication
+ - Minecraft Version Management
+ - Mod Loaders (Fabric/Forge)
+ - Java Installation and Configuration
+ - Game Launch Issues
+ - Settings and Configuration
+ - Building from Source
+ - Contributing to the Project
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Your Question
+ description: Please describe your question in detail
+ placeholder: What would you like to know?
+ validations:
+ required: true
+
+ - type: input
+ id: version
+ attributes:
+ label: DropOut Version (if applicable)
+ description: What version of DropOut are you using?
+ placeholder: "e.g., 0.1.23"
+ validations:
+ required: false
+
+ - type: dropdown
+ id: os
+ attributes:
+ label: Operating System (if applicable)
+ description: Which operating system are you using?
+ options:
+ - Windows
+ - macOS
+ - Linux
+ - Not applicable
+ validations:
+ required: false
+
+ - type: textarea
+ id: context
+ attributes:
+ label: Additional Context
+ description: Add any other context, screenshots, or information that might help us answer your question
+ placeholder: Any additional details...
+ validations:
+ required: false
diff --git a/.github/PULL_REQUEST_TEMPLATE/cn-pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/cn-pull_request_template.md
new file mode 100644
index 0000000..abcbaa1
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE/cn-pull_request_template.md
@@ -0,0 +1,127 @@
+# 描述
+
+<!-- 简要描述此 PR 的更改内容 -->
+
+## 更改类型
+
+<!-- 用 "x" 标记相关选项 -->
+
+- [ ] Bug 修复(修复问题的非破坏性更改)
+- [ ] 新功能(添加功能的非破坏性更改)
+- [ ] 破坏性更改(会导致现有功能无法正常工作的修复或功能)
+- [ ] 文档更新
+- [ ] UI/UX 改进
+- [ ] 性能优化
+- [ ] 代码重构(无功能性更改)
+- [ ] 配置更改
+- [ ] 测试添加或更新
+
+## LLM 生成代码声明
+
+<!-- 如果此 PR 包含 LLM 生成的代码,请在此声明 -->
+
+- [ ] 此 PR 包含 LLM 生成的代码,我**提供**质量担保
+- [ ] 此 PR 包含 LLM 生成的代码,我**不提供**质量担保
+- [ ] 此 PR 不包含 LLM 生成的代码
+
+## 相关 Issue
+
+<!-- 使用 #issue_number 链接相关 issue -->
+
+关闭 #
+相关 #
+
+## 更改内容
+
+<!-- 详细描述更改内容 -->
+
+### 后端 (Rust)
+
+-
+
+### 前端 (Svelte)
+
+-
+
+### 配置
+
+-
+
+## 测试
+
+<!-- 描述你运行的测试以及如何复现 -->
+
+### 测试环境
+
+- **操作系统**:<!-- 例如:Windows 11、macOS 14、Ubuntu 22.04 -->
+- **DropOut 版本**:<!-- 例如:0.1.23 -->
+- **测试的 Minecraft 版本**:<!-- 例如:1.21.1 -->
+- **Mod 加载器**:<!-- 例如:Fabric 0.16.0、Forge 49.0.3 或 无 -->
+
+### 测试用例
+
+- [ ] 已在 Windows 上测试
+- [ ] 已在 macOS 上测试
+- [ ] 已在 Linux 上测试
+- [ ] 已测试原版 Minecraft
+- [ ] 已测试 Fabric
+- [ ] 已测试 Forge
+- [ ] 已测试游戏启动
+- [ ] 已测试登录流程
+- [ ] 已测试 Java 检测/下载
+
+### 测试步骤
+
+1.
+2.
+3.
+
+## 检查清单
+
+<!-- 用 "x" 标记已完成的项目 -->
+
+### 代码质量
+
+- [ ] 我的代码遵循项目的代码风格指南
+- [ ] 我已对自己的代码进行了自审
+- [ ] 我已对难以理解的区域添加了注释
+- [ ] 我的更改没有产生新的警告或错误
+
+### 测试验证
+
+- [ ] 我已在本地测试了我的更改
+- [ ] 我已添加测试来证明我的修复有效或功能正常工作
+- [ ] 新的和现有的单元测试在本地通过
+- [ ] 我至少在一个目标平台上进行了测试
+
+### 文档更新
+
+- [ ] 我已相应地更新了文档
+- [ ] 如有需要,我已更新 README
+- [ ] 我已在必要处添加/更新代码注释
+
+### 依赖项
+
+- [ ] 我已检查没有添加不必要的依赖项
+- [ ] 所有新依赖项都已正确记录
+- [ ] `Cargo.lock` 和/或 `pnpm-lock.yaml` 已更新(如果依赖项有变化)
+
+## 截图 / 视频
+
+<!-- 如适用,添加截图或视频来展示更改 -->
+
+## 附加说明
+
+<!-- 在此添加关于此 PR 的其他上下文 -->
+
+## 破坏性更改说明
+
+<!-- 如果这是破坏性更改,请描述用户的迁移路径 -->
+
+---
+
+**维护者专用:**
+
+- [ ] 代码审查已完成
+- [ ] CI 检查通过
+- [ ] 准备合并
diff --git a/.github/PULL_REQUEST_TEMPLATE/en-pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/en-pull_request_template.md
new file mode 100644
index 0000000..79a8148
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE/en-pull_request_template.md
@@ -0,0 +1,127 @@
+# Description
+
+<!-- Provide a brief description of the changes in this PR -->
+
+## Type of Change
+
+<!-- Mark the relevant option with an "x" -->
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] Documentation update
+- [ ] UI/UX improvement
+- [ ] Performance improvement
+- [ ] Code refactoring (no functional changes)
+- [ ] Configuration change
+- [ ] Test addition or update
+
+## LLM-Generated Code Disclosure
+
+<!-- If this PR contains LLM-generated code, please disclose it here -->
+
+- [ ] This PR contains LLM-generated code, and I **provide** quality assurance
+- [ ] This PR contains LLM-generated code, and I **do not provide** quality assurance
+- [ ] This PR does not contain LLM-generated code
+
+## Related Issues
+
+<!-- Link to related issues using #issue_number -->
+
+Closes #
+Related to #
+
+## Changes Made
+
+<!-- Describe the changes in detail -->
+
+### Backend (Rust)
+
+-
+
+### Frontend (Svelte)
+
+-
+
+### Configuration
+
+-
+
+## Testing
+
+<!-- Describe the tests you ran and how to reproduce them -->
+
+### Test Environment
+
+- **OS**: <!-- e.g., Windows 11, macOS 14, Ubuntu 22.04 -->
+- **DropOut Version**: <!-- e.g., 0.1.23 -->
+- **Minecraft Version Tested**: <!-- e.g., 1.21.1 -->
+- **Mod Loader**: <!-- e.g., Fabric 0.16.0, Forge 49.0.3, or N/A -->
+
+### Test Cases
+
+- [ ] Tested on Windows
+- [ ] Tested on macOS
+- [ ] Tested on Linux
+- [ ] Tested with vanilla Minecraft
+- [ ] Tested with Fabric
+- [ ] Tested with Forge
+- [ ] Tested game launch
+- [ ] Tested authentication flow
+- [ ] Tested Java detection/download
+
+### Steps to Test
+
+1.
+2.
+3.
+
+## Checklist
+
+<!-- Mark completed items with an "x" -->
+
+### Code Quality
+
+- [ ] My code follows the project's style guidelines
+- [ ] I have performed a self-review of my own code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] My changes generate no new warnings or errors
+
+### Testing Verification
+
+- [ ] I have tested my changes locally
+- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] New and existing unit tests pass locally with my changes
+- [ ] I have tested on at least one target platform
+
+### Documentation
+
+- [ ] I have updated the documentation accordingly
+- [ ] I have updated the README if needed
+- [ ] I have added/updated code comments where necessary
+
+### Dependencies
+
+- [ ] I have checked that no unnecessary dependencies were added
+- [ ] All new dependencies are properly documented
+- [ ] `Cargo.lock` and/or `pnpm-lock.yaml` are updated (if dependencies changed)
+
+## Screenshots / Videos
+
+<!-- If applicable, add screenshots or videos to demonstrate the changes -->
+
+## Additional Notes
+
+<!-- Add any other context about the PR here -->
+
+## Breaking Changes
+
+<!-- If this is a breaking change, describe the migration path for users -->
+
+---
+
+**For Maintainers:**
+
+- [ ] Code review completed
+- [ ] CI checks passing
+- [ ] Ready to merge
diff --git a/.github/agents/commit.agent.md b/.github/agents/commit.agent.md
new file mode 100644
index 0000000..7187402
--- /dev/null
+++ b/.github/agents/commit.agent.md
@@ -0,0 +1,260 @@
+# Commit Helper Agent
+
+You are a Git commit message assistant following the Conventional Commits specification.
+
+## Task
+
+Generate well-structured commit messages based on staged changes or user descriptions.
+
+## Commit Format
+
+```
+<type>[optional scope]: <description>
+
+[optional body]
+
+[optional footer(s)]
+```
+
+## Workflow Rules
+
+### Language Policy
+
+1. **Commit message language**: ALWAYS write in **English** unless user explicitly requests another language
+2. **Explanation language**: Use the **same language as user's request**
+3. **Translation rule**: If commit language ≠ user's language → provide explanation
+ - User speaks Chinese + English commit → Explain in Chinese
+ - User speaks English + Chinese commit → Explain in English
+ - User speaks English + English commit → No extra explanation needed
+ - User speaks Chinese + Chinese commit → No extra explanation needed
+
+### Confirmation Policy
+
+**ALWAYS ask for confirmation before committing** unless user explicitly says:
+- "commit directly"
+- "commit immediately"
+- "just commit it"
+
+**Standard flow**:
+1. Generate commit message
+2. Explain what it means (in user's language if different from English)
+3. Show the command: `git commit -m "..."`
+4. Ask: "Proceed with this commit?" (in user's language)
+5. Only execute if user confirms
+
+### Step 0: Check Current Branch (REQUIRED)
+
+**Before doing anything**, check the current branch and validate:
+
+1. Run `git branch --show-current` to get current branch name
+2. Run `git status` to see if there are any changes
+3. **Validate branch naming**:
+ - Feature work → Should be on `feat/*` or `feature/*` branch
+ - Bug fixes → Should be on `fix/*` or `bugfix/*` branch
+ - Documentation → Should be on `docs/*` branch
+ - Refactoring → Should be on `refactor/*` branch
+ - Hotfix → Should be on `hotfix/*` branch
+
+4. **Branch validation rules**:
+ - If on `main` or `master` → WARN: "You're on the main branch. Consider creating a feature branch first."
+ - If branch name doesn't match change type → WARN: "Current branch is `X`, but changes look like `Y` type. Continue or switch branch?"
+ - If branch name matches change type → Proceed silently
+
+**Example warnings**:
+```
+On main + adding feature:
+ "You're on main branch. Consider: git checkout -b feat/your-feature-name"
+
+On feat/ui-update + fixing bug:
+ "Current branch is feat/ui-update but changes look like a bug fix.
+ Consider: git checkout -b fix/bug-name or continue on current branch?"
+
+On docs/readme + adding code:
+ "Current branch is docs/readme but changes include code modifications.
+ Consider switching to feat/* or fix/* branch?"
+```
+
+If user chooses to continue, proceed to generate commit message as normal.
+
+### Step 1: Analyze Changes
+
+When user asks for a commit message:
+
+1. **If changes are staged**: Run `git diff --cached --stat` to see what files changed
+2. **If specific files mentioned**: Run `git diff <file>` to understand the changes
+3. **If user describes changes**: Use their description directly
+
+### Step 2: Determine Type
+
+| Type | When to Use |
+|------|-------------|
+| `feat` | New feature for the user |
+| `fix` | Bug fix |
+| `docs` | Documentation only changes |
+| `style` | Formatting, missing semicolons, etc. (no code change) |
+| `refactor` | Code change that neither fixes a bug nor adds a feature |
+| `perf` | Performance improvement |
+| `test` | Adding or updating tests |
+| `build` | Changes to build system or dependencies |
+| `ci` | CI configuration changes |
+| `chore` | Other changes that don't modify src or test files |
+| `revert` | Reverts a previous commit |
+
+**Quick Decision Tree**:
+```
+Changes involve...
+├─ New user-facing feature? → feat
+├─ Fix user-reported bug? → fix
+├─ Only docs/comments? → docs
+├─ Internal refactor? → refactor
+├─ Performance improvement? → perf
+└─ Breaking API change? → Add ! + BREAKING CHANGE footer
+```
+
+### Step 3: Determine Scope (Optional)
+
+Scope should be a noun describing the section of codebase:
+- `feat(gui)`: GUI-related feature
+- `fix(memory)`: Memory-related fix
+- `docs(api)`: API documentation
+- `refactor(core)`: Core module refactoring
+
+### Step 4: Write Description
+
+- Use imperative mood: "add" not "added" or "adds"
+- Don't capitalize first letter
+- No period at the end
+- Keep under 50 characters
+
+**Common mistakes**:
+- ❌ `Added new feature` → ✅ `add new feature`
+- ❌ `Fix bug.` → ✅ `fix authentication issue`
+- ❌ Multiple concerns → Split into separate commits
+
+### Step 5: Add Body (If Needed)
+
+- Explain WHAT and WHY, not HOW
+- Wrap at 72 characters
+- Separate from description with blank line
+
+### Step 6: Add Footer (If Needed)
+
+**Breaking Changes**:
+```
+BREAKING CHANGE: <description>
+```
+
+**AI-Generated Commits** (REQUIRED for AI assistance):
+```
+Reviewed-by: [MODEL_NAME]
+```
+
+**Issue References**:
+```
+Refs #123
+Closes #456
+```
+
+## Examples
+
+### Simple Feature
+```
+feat(gui): add transparent window support
+```
+
+### Bug Fix with Body
+```
+fix(memory): resolve index memory leak
+
+The index was not being properly released when switching
+between different memory contexts, causing gradual memory
+growth over extended sessions.
+
+Reviewed-by: [MODEL_NAME]
+```
+
+### Breaking Change
+```
+refactor(core)!: restructure plugin system
+
+Plugin API now requires explicit registration instead of
+auto-discovery. This improves startup time but requires
+migration of existing plugins.
+
+BREAKING CHANGE: Plugin API signature changed from
+`register()` to `register(manifest: PluginManifest)`
+
+Reviewed-by: [MODEL_NAME]
+```
+
+### Documentation Update
+```
+docs: update PRD with new interaction flow
+
+Reviewed-by: [MODEL_NAME]
+```
+
+### Multiple Changes (use most significant type)
+```
+feat(state): add mood decay system with persistence
+
+- Implement time-based mood decay algorithm
+- Add SQLite persistence for mood state
+- Create mood recovery mechanics
+
+Reviewed-by: [MODEL_NAME]
+Refs #42
+```
+
+## Commands
+
+When user says "create commit" or "commit message":
+
+1. **[REQUIRED]** Check current branch and validate (Step 0)
+2. Ask what changes to commit (or analyze staged changes)
+3. Generate commit message in **English** (following Conventional Commits format)
+4. **If commit language is not user's language**: Explain the commit in user's language
+5. **Always ask for confirmation** before executing (unless user said "commit directly" or similar)
+6. If confirmed, run: `git commit -m "<message>"`
+
+**Example 1 (Chinese user, English commit)**:
+```
+User: "帮我提交这个功能"
+AI: "建议的提交信息:
+ feat(gui): add transparent window support
+
+ 这个提交添加了透明窗口功能。是否执行此提交?"
+User: "是" or "直接提交" or "y"
+AI: [executes git commit]
+```
+
+**Example 2 (English user, Chinese commit)**:
+```
+User: "write a Chinese commit for this feature"
+AI: "Suggested commit:
+ feat(gui): 添加透明窗口支持
+
+ This commit adds transparent window support. Proceed?"
+User: "yes" or "commit directly" or "y"
+AI: [executes git commit]
+```
+
+**Example 3 (English user, English commit - no explanation)**:
+```
+User: "commit this feature"
+AI: "Suggested commit:
+ feat(gui): add transparent window support
+
+ Proceed with this commit?"
+User: "yes" or "commit directly" or "y"
+AI: [executes git commit]
+```
+
+When user says "amend commit":
+```bash
+git commit --amend -m "<new message>"
+```
+
+## References
+
+- Commit spec: <a>.github/references/git/conventional-commit.md</a>
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..6b577d4
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,289 @@
+# DropOut Minecraft Launcher - AI Development Guide
+
+## Architecture Overview
+
+**DropOut** is a Tauri v2 desktop application combining:
+- **Backend (Rust)**: Game launching, asset management, authentication, mod loader installation
+- **Frontend (Svelte 5)**: Reactive UI with Tailwind CSS 4 and particle effects
+- **Communication**: Tauri commands (invoke) and events (emit/listen)
+- **Pre-commit Hooks**: Python-based tooling for JSON/TOML validation (managed via `pyproject.toml`)
+
+**Key Data Flow**: Frontend invokes Rust commands → Rust processes/downloads → Rust emits progress events → Frontend updates UI via listeners
+
+**Version Management**: Uses `_version.py` for single source of truth, synced to `Cargo.toml` (0.1.24) and `tauri.conf.json`
+
+## Project Structure
+
+```
+src-tauri/ # Rust backend
+ src/
+ main.rs # Tauri commands, game launch logic, event emissions
+ core/ # Core modules (auth, downloader, fabric, forge, java, etc.)
+ mod.rs # Module declarations
+ auth.rs # Microsoft OAuth + offline auth via Device Code Flow
+ downloader.rs # Concurrent downloads with progress tracking, resumable downloads
+ fabric.rs # Fabric loader installation and version management
+ forge.rs # Forge installer execution and profile generation
+ java.rs # Java detection, Adoptium download/install, catalog management
+ config.rs # LauncherConfig (memory, java path, download threads)
+ game_version.rs # Minecraft version JSON parsing
+ manifest.rs # Mojang version manifest fetching
+ maven.rs # Maven artifact URL resolution for mod loaders
+ rules.rs # OS/feature rule evaluation for libraries
+ version_merge.rs # Parent version inheritance merging
+ utils/
+ zip.rs # Native library extraction
+ui/ # Svelte 5 frontend
+ src/
+ App.svelte # Main app component, enforces dark mode
+ stores/ # Svelte 5 runes state management ($state, $effect)
+ auth.svelte.ts # Authentication state with device code polling
+ game.svelte.ts # Game state (running, logs)
+ settings.svelte.ts # Settings + Java detection
+ ui.svelte.ts # UI state (toasts, modals, active view)
+ components/ # UI components (HomeView, VersionsView, SettingsView, etc.)
+ lib/ # Reusable components (DownloadMonitor, GameConsole)
+```
+
+## Critical Development Workflows
+
+### Development Mode
+```bash
+cargo tauri dev # Starts frontend dev server (Vite on :5173) + Tauri window
+```
+- Frontend uses **Rolldown-based Vite fork** (`npm:rolldown-vite@7.2.5`) with hot reload
+- Backend recompiles on Rust file changes
+- Console shows both Rust stdout and frontend Vite logs
+- **Vite Config**: Uses `usePolling: true` for watch compatibility with Tauri
+- **HMR**: WebSocket on `ws://localhost:5173`
+
+### Pre-commit Checks
+- Uses **pre-commit** with Python (configured in `pyproject.toml`)
+- Hooks: JSON/TOML/YAML validation, Ruff for Python files
+- Run manually: `pre-commit run --all-files`
+- **IMPORTANT**: All Python tooling for CI/validation lives here, NOT for app logic
+
+### Building
+```bash
+cd ui && pnpm install # Install frontend dependencies (requires pnpm 9, Node 22)
+cargo tauri build # Produces platform bundles in src-tauri/target/release/bundle/
+```
+
+### Frontend Workflows
+```bash
+cd ui
+pnpm check # Svelte type checking + TypeScript validation
+pnpm lint # OxLint for code quality
+pnpm format # OxFmt for formatting (--check for CI)
+```
+
+### Testing
+- CI workflow: [`.github/workflows/test.yml`](.github/workflows/test.yml) tests on Ubuntu, Arch (Wayland), Windows, macOS
+- Local: `cargo test` (no comprehensive test suite exists yet)
+- **Test workflow behavior**: Push/PR = Linux build only, `workflow_dispatch` = full multi-platform builds
+
+## Project-Specific Patterns & Conventions
+
+### Tauri Command Pattern
+Commands in [`main.rs`](../src-tauri/src/main.rs) follow this structure:
+```rust
+#[tauri::command]
+async fn command_name(
+ window: Window,
+ state: State<'_, SomeState>,
+ param: Type,
+) -> Result<ReturnType, String> {
+ emit_log!(window, "Status message"); // Emits "launcher-log" event
+ // ... async logic
+ Ok(result)
+}
+```
+**Register in `main()`:**
+```rust
+tauri::Builder::default()
+ .invoke_handler(tauri::generate_handler![command_name, ...])
+```
+
+### Event Communication
+**Rust → Frontend (Progress/Logs):**
+```rust
+// In Rust
+window.emit("launcher-log", "Downloading assets...")?;
+window.emit("download-progress", progress_struct)?;
+```
+```typescript
+// In Frontend (Svelte)
+import { listen } from "@tauri-apps/api/event";
+const unlisten = await listen("launcher-log", (event) => {
+ console.log(event.payload);
+});
+```
+
+**Frontend → Rust (Commands):**
+```typescript
+import { invoke } from "@tauri-apps/api/core";
+const result = await invoke("start_game", { versionId: "1.20.4" });
+```
+
+### State Management (Rust)
+Global state via Tauri's managed state:
+```rust
+pub struct ConfigState {
+ pub config: Mutex<LauncherConfig>,
+ pub file_path: PathBuf,
+}
+// In main:
+.manage(ConfigState::new(&app_handle))
+// In commands:
+config_state: State<'_, ConfigState>
+```
+
+### State Management (Svelte 5)
+Uses **Svelte 5 runes** (not stores):
+```typescript
+// stores/auth.svelte.ts
+export class AuthState {
+ currentAccount = $state<Account | null>(null); // Reactive state
+ isLoginModalOpen = $state(false);
+
+ $effect(() => { // Side effects
+ // Runs when dependencies change
+ });
+}
+// Export singleton
+export const authState = new AuthState();
+```
+**CRITICAL**: Stores are TypeScript classes with `$state` runes, not Svelte 4's `writable()`. Each store file exports a singleton instance.
+
+**Store Pattern**:
+- File: `stores/*.svelte.ts` (note `.svelte.ts` extension)
+- Class-based with reactive `$state` properties
+- Methods for actions (async operations with `invoke()`)
+- Derived values with `get` accessors
+- Side effects with `$effect()` (auto-tracks dependencies)
+
+### Version Inheritance System
+Modded versions (Fabric/Forge) use `inheritsFrom` field:
+- [`version_merge.rs`](../src-tauri/src/core/version_merge.rs): Merges parent vanilla JSON with mod loader JSON
+- [`manifest.rs`](../src-tauri/src/core/manifest.rs): `load_version()` recursively resolves inheritance
+- Libraries, assets, arguments are merged from parent + modded version
+
+### Microsoft Authentication Flow
+Uses **Device Code Flow** (no redirect needed):
+1. Frontend calls `start_microsoft_login()` → gets device code + URL
+2. User visits URL in browser, enters code
+3. Frontend polls `complete_microsoft_login()` with device code
+4. Rust exchanges code → MS token → Xbox Live → XSTS → Minecraft token
+5. Stores MS refresh token for auto-refresh (see [`auth.rs`](../src-tauri/src/core/auth.rs))
+
+**Client ID**: Uses ATLauncher's public client ID (`c36a9fb6-4f2a-41ff-90bd-ae7cc92031eb`)
+
+### Download System
+[`downloader.rs`](../src-tauri/src/core/downloader.rs) features:
+- **Concurrent downloads** with semaphore (configurable threads)
+- **Resumable downloads**: `.part` + `.part.meta` files track progress
+- **Multi-segment downloads**: Large files split into segments downloaded in parallel
+- **Checksum verification**: SHA1/SHA256 validation
+- **Progress events**: Emits `download-progress` with file name, bytes, ETA
+- **Queue persistence**: Java downloads saved to `download_queue.json` for resumption
+
+### Java Management
+[`java.rs`](../src-tauri/src/core/java.rs):
+- **Auto-detection**: Scans `/usr/lib/jvm`, `/Library/Java`, `JAVA_HOME`, `PATH`
+- **Adoptium API**: Fetches available JDK/JRE versions for current OS/arch
+- **Catalog caching**: `java_catalog.json` cached for 24 hours
+- **Installation**: Downloads, extracts to `app_data_dir/java/<version>`
+- **Cancellation**: Global `AtomicBool` flag for download cancellation
+
+### Error Handling
+- Commands return `Result<T, String>` (String for JS-friendly errors)
+- Use `.map_err(|e| e.to_string())` to convert errors
+- Emit detailed error logs: `emit_log!(window, format!("Error: {}", e))`
+
+### File Paths
+- **Game directory**: `app_handle.path().app_data_dir()` (~/.local/share/com.dropout.launcher on Linux)
+- **Versions**: `game_dir/versions/<version_id>/<version_id>.json`
+- **Libraries**: `game_dir/libraries/<maven-path>`
+- **Assets**: `game_dir/assets/objects/<hash[0..2]>/<hash>`
+- **Config**: `game_dir/config.json`
+- **Accounts**: `game_dir/accounts.json`
+
+## Integration Points
+
+### External APIs
+- **Mojang**: `https://piston-meta.mojang.com/mc/game/version_manifest_v2.json`
+- **Fabric Meta**: `https://meta.fabricmc.net/v2/`
+- **Forge Maven**: `https://maven.minecraftforge.net/`
+- **Adoptium**: `https://api.adoptium.net/v3/`
+- **GitHub Releases**: `https://api.github.com/repos/HsiangNianian/DropOut/releases`
+
+### Native Dependencies
+- **Linux**: `libwebkit2gtk-4.1-dev`, `libgtk-3-dev` (see [test.yml](../.github/workflows/test.yml))
+- **macOS**: System WebKit via Tauri
+- **Windows**: WebView2 runtime (bundled)
+
+## Common Tasks
+
+### Adding a New Tauri Command
+1. Define function in [`main.rs`](../src-tauri/src/main.rs) with `#[tauri::command]`
+2. Add to `.invoke_handler(tauri::generate_handler![..., new_command])`
+3. Call from frontend: `invoke("new_command", { args })`
+
+### Adding a New UI View
+1. Create component in `ui/src/components/NewView.svelte`
+2. Import in [`App.svelte`](../ui/src/App.svelte)
+3. Add navigation in [`Sidebar.svelte`](../ui/src/components/Sidebar.svelte)
+4. Update `uiState.activeView` in [`ui.svelte.ts`](../ui/src/stores/ui.svelte.ts)
+
+### Emitting Progress Events
+Use `emit_log!` macro for launcher logs:
+```rust
+emit_log!(window, format!("Downloading {}", filename));
+```
+For custom events:
+```rust
+window.emit("custom-event", payload)?;
+```
+
+### Handling Placeholders in Arguments
+Game arguments may contain `${variable}` placeholders. Use the `has_unresolved_placeholder()` helper to skip malformed arguments (see [`main.rs:57-67`](../src-tauri/src/main.rs#L57-L67)).
+
+## Important Notes
+
+- **Dark mode enforced**: [`App.svelte`](../ui/src/App.svelte) force-adds `dark` class regardless of system preference
+- **Svelte 5 syntax**: Use `$state`, `$derived`, `$effect` (not `writable` stores)
+- **No CREATE_NO_WINDOW on non-Windows**: Use `#[cfg(target_os = "windows")]` for Windows-specific code
+- **Version IDs**: Fabric uses `fabric-loader-<loader>-<game>`, Forge uses `<game>-forge-<loader>`
+- **Mod loader libraries**: Don't have `downloads.artifact`, use Maven resolution via [`maven.rs`](../src-tauri/src/core/maven.rs)
+- **Native extraction**: Extract to `versions/<version>/natives/`, exclude META-INF
+- **Classpath order**: Libraries → Client JAR (see [`main.rs:437-453`](../src-tauri/src/main.rs#L437-L453))
+- **Version management**: Single source in `_version.py`, synced to Cargo.toml and tauri.conf.json
+- **Frontend dependencies**: Must use pnpm 9 + Node 22 (uses Rolldown-based Vite fork)
+- **Store files**: Must have `.svelte.ts` extension, not `.ts`
+
+## Debugging Tips
+
+- **Rust logs**: Check terminal running `cargo tauri dev`
+- **Frontend logs**: Browser devtools (Ctrl+Shift+I in Tauri window)
+- **Game logs**: Listen to `game-stdout`/`game-stderr` events
+- **Download issues**: Check `download-progress` events, validate SHA1 hashes
+- **Auth issues**: MS WAF blocks requests without User-Agent (see [`auth.rs:6-12`](../src-tauri/src/core/auth.rs#L6-L12))
+
+## Version Compatibility
+
+- **Rust**: Edition 2021, requires Tauri v2 dependencies
+- **Node.js**: 22+ with pnpm 9+ for frontend (uses Rolldown-based Vite fork `npm:rolldown-vite@7.2.5`)
+- **Tauri**: v2.9+
+- **Svelte**: v5.46+ (runes mode)
+- **Java**: Supports detection of Java 8-23+, recommends Java 17+ for modern Minecraft
+- **Python**: 3.10+ for pre-commit hooks (validation only, not app logic)
+
+## Commit Conventions
+
+Follow instructions in [`.github/instructions/commit.instructions.md`](.github/instructions/commit.instructions.md):
+- **Format**: `<type>[scope]: <description>` (lowercase, imperative, no period)
+- **AI commits**: MUST include `Reviewed-by: [MODEL_NAME]`
+- **Common types**: `feat`, `fix`, `docs`, `refactor`, `perf`, `test`, `chore`
+- **Language**: Commit messages ALWAYS in English
+- **Confirmation**: ALWAYS ask before committing (unless "commit directly" requested)
+- See [Conventional Commits spec](.github/references/git/conventional-commit.md) for details
diff --git a/.github/instructions/commit.instructions.md b/.github/instructions/commit.instructions.md
new file mode 100644
index 0000000..f01f080
--- /dev/null
+++ b/.github/instructions/commit.instructions.md
@@ -0,0 +1,38 @@
+---
+applyTo: "**"
+---
+
+# Commit Helper Instructions
+
+When user requests commit help → Follow <a>.github/agents/commit.agent.md</a>
+
+## Critical Rules
+
+1. **Language**: Commit message ALWAYS in **English** (unless user specifies otherwise)
+2. **Explanation**: Use **user's request language** ONLY when commit language differs
+ - Chinese user + English commit → Explain in Chinese
+ - English user + Chinese commit → Explain in English
+ - Same language → No extra explanation needed
+3. **Confirmation**: ALWAYS ask before committing (unless "commit directly" requested)
+
+## Quick Reference
+
+**Format**: `<type>[scope]: <description>`
+
+**Common types**: `feat` `fix` `docs` `refactor` `perf` `test` `chore`
+
+**AI commits MUST include**: `Reviewed-by: [MODEL_NAME]`
+
+**Spec**: <a>.github/references/git/conventional-commit.md</a>
+
+## Common Mistakes
+
+| Wrong | Right |
+|-------|-------|
+| `feat: Added feature` | `feat: add feature` (imperative) |
+| `Fix bug.` | `fix: resolve auth issue` (lowercase, no period) |
+| `feat: add A, refactor B, update C` | Split into 3 commits |
+
+## User Triggers
+
+"create commit", "commit message", "conventional commit"
diff --git a/.github/references/git/conventional-commit.md b/.github/references/git/conventional-commit.md
new file mode 100644
index 0000000..a9e27bc
--- /dev/null
+++ b/.github/references/git/conventional-commit.md
@@ -0,0 +1,153 @@
+# What is Conventional Commits?
+
+> A standard for writing commit messages.
+
+## Table of Contents
+
+- [What is Conventional Commits?](#what-is-conventional-commits)
+- [Examples](#examples)
+- [Rules](#rules)
+- [Why Should We Use It?](#why-should-we-use-it)
+- [Changelog Generation](#changelog-generation)
+- [Bump the Version Precisely](#bump-the-version-precisely)
+- [How About Squash Merges?](#how-about-squash-merges)
+
+The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of. This convention dovetails with [SemVer](https://semver.org/), by describing the features, fixes, and breaking changes made in commit messages.
+
+```text
+<type>[optional scope]: <description>
+
+[optional body]
+
+[optional footer(s)]
+```
+
+## Examples
+
+> Commit message with scope
+
+```text
+feat(SHOPPER-000): introduce OrderMonitor v2
+```
+
+> Commit message with breaking change
+
+```text
+refactor!: drop support for Node 6
+```
+
+> Commit message with footer and breaking change
+
+```text
+feat: enhance error handling
+
+BREAKING CHANGE: Modified every error message and added the error key
+```
+
+> Commit message with multi-paragraph body and multiple footers
+
+```text
+fix(SHOPPER-000): correct minor typos in code
+
+see the issue for details
+
+on typos fixed.
+
+Reviewed-by: Z
+Refs #133
+```
+
+> Here reviewer should be replaced with the actual name of the reviewer or the **model name card** like "GPT-4o mini" by default.
+
+## Rules
+
+The key words **“MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL”** in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
+
+- Commits MUST be prefixed with a type, which consists of a noun, feat, fix, etc., followed by the OPTIONAL scope, OPTIONAL !, and REQUIRED terminal colon and space.
+- The type feat MUST be used when a commit adds a new feature to your application or library.
+- The type fix MUST be used when a commit represents a bug fix for your application.
+- A scope MAY be provided after a type. A scope MUST consist of a noun describing a section of the codebase surrounded by parenthesis, e.g., fix(parser):
+- A description MUST immediately follow the colon and space after the type/scope prefix. The description is a short summary of the code changes, e.g., fix: array parsing issue when multiple spaces were contained in string.
+- A longer commit body MAY be provided after the short description, providing additional contextual information about the code changes. The body MUST begin one blank line after the description.
+- A commit body is free-form and MAY consist of any number of newline separated paragraphs.
+- One or more footers MAY be provided one blank line after the body. Each footer MUST consist of a word token, followed by either a :<space> or <space># separator, followed by a string value (this is inspired by the git trailer convention).
+- A footer’s token MUST use - in place of whitespace characters, e.g., Acked-by (this helps differentiate the footer section from a multi-paragraph body). An exception is made for BREAKING CHANGE, which MAY also be used as a token.
+- A footer’s value MAY contain spaces and newlines, and parsing MUST terminate when the next valid footer token/separator pair is observed.
+- Breaking changes MUST be indicated in the type/scope prefix of a commit, or as an entry in the footer.
+- If included as a footer, a breaking change MUST consist of the uppercase text BREAKING CHANGE, followed by a colon, space, and description, e.g., BREAKING CHANGE: environment variables now take precedence over config files.
+If included in the type/scope prefix, breaking changes MUST be indicated by a ! immediately before the :. If ! is used, BREAKING CHANGE: MAY be omitted from the footer section, and the commit description SHALL be used to describe the breaking change.
+- Types other than feat and fix MAY be used in your commit messages, e.g., docs: updated ref docs.
+- The units of information that make up Conventional Commits MUST NOT be treated as case sensitive by implementors, with the exception of BREAKING CHANGE which MUST be uppercase.
+- BREAKING-CHANGE MUST be synonymous with BREAKING CHANGE, when used as a token in a footer.
+
+## Why Should We Use It?
+
+- Automatic changelog generation
+- The context information that refers to business initiative when it's needed
+- Noticeable breaking changes
+- Forces us to write better commit messages (no more vague 'fix', 'refactor' commits)
+- Bumping version precisely
+- Making it easier to contribute to the projects by allowing contributors to explore a more structured commit history
+
+## Changelog Generation
+
+### Why Changelog?
+
+A changelog is a file that contains a curated, chronologically ordered list of notable changes for each version of a project to make it easier for users and contributors.
+
+For more information, see the [Keep a Changelog](https://keepachangelog.com/) standard.
+
+### Why Generate Changelogs via Conventional Commits?
+
+It's hard to maintain changelogs by hand and most of the time it fails. Manual changelog updates lead to:
+
+- Discrepancy between docs and actual versions
+- Missing breaking changes
+- Outdated changelogs
+
+You can automate the process of generating changelogs via GitHub Actions or locally via git hooks, which speeds up the process significantly.
+
+## Bump the Version Precisely
+
+### Benefits of Bumping Version Through Conventional Commits
+
+- We shouldn't depend on one owner who knows every change between releases
+- Every contributor should decide the impact of their changes during the development process
+- You can auto-bump the version once it's merged to a specific branch (no more forgotten version updates)
+- See [Conventional Commits Version Bump](https://github.com/marketplace/actions/conventional-commits-version-bump) GitHub Action
+- Speeds up the process
+- Prevents human mistakes
+
+**Major Version Bump**
+
+```text
+refactor!: drop support for Node 6
+```
+
+**Minor Version Bump**
+
+```text
+feat(SHOPPER-000): introduce OrderMonitor v2
+```
+
+**Patch Version Bump**
+
+```text
+fix(SHOPPER-000): correct minor typos in code
+```
+
+## How About Squash Merges?
+
+Why do we need squash merges if we have good commit messages?
+
+### Pros
+
+- Every squash commit linked to PR
+- Cleaner git history
+- Easy roll-back
+
+### Cons
+
+- It changes commit history, which can cause conflicts
+- It's hard to understand what actually changed
+- Sometimes what you commit is not related to the purpose of the PR
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 58fc378..ba8ce54 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -13,6 +13,8 @@ on:
jobs:
check:
+ permissions:
+ contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -38,6 +40,6 @@ jobs:
- run: pnpm lint
working-directory: ui
- - run: pnpm format --check
+ - run: pnpm format
working-directory: ui
diff --git a/.github/workflows/issue-checkbox-checker.yml b/.github/workflows/issue-checkbox-checker.yml
new file mode 100644
index 0000000..ce7e011
--- /dev/null
+++ b/.github/workflows/issue-checkbox-checker.yml
@@ -0,0 +1,104 @@
+name: Issue Checkbox Checker
+
+on:
+ issues:
+ types: [opened, edited]
+
+permissions:
+ issues: write
+
+jobs:
+ check-checkboxes:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check for unchecked prerequisites
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const issue = context.payload.issue;
+ if (!issue) return;
+
+ const body = issue.body || '';
+
+ // Check if "I have not read carefully" checkbox is checked
+ const notReadPatterns = [
+ /- \[[xX]\] I have not read carefully/,
+ /- \[[xX]\] 我未仔细阅读/
+ ];
+
+ const hasNotReadChecked = notReadPatterns.some(pattern => pattern.test(body));
+
+ if (hasNotReadChecked) {
+ const closeMessage = [
+ '## Issue Automatically Closed / Issue 已自动关闭',
+ '',
+ '**English:**',
+ 'This issue has been automatically closed because you checked "I have not read carefully."',
+ '',
+ 'Please:',
+ '1. Read the [README](https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/blob/main/README.md) and documentation carefully',
+ '2. Search for existing issues',
+ '3. Fill out the issue template completely',
+ '4. Submit a new issue when ready',
+ '',
+ '**中文:**',
+ '此 Issue 已被自动关闭,因为您勾选了"我未仔细阅读"。',
+ '',
+ '请:',
+ '1. 仔细阅读 [README](https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/blob/main/README.md) 和文档',
+ '2. 搜索现有 Issue',
+ '3. 完整填写 Issue 模板',
+ '4. 准备好后提交新的 Issue',
+ '',
+ '---',
+ '*This is an automated action. If you believe this was done in error, please contact the maintainers.*'
+ ].join('\n');
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issue.number,
+ body: closeMessage
+ });
+
+ await github.rest.issues.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issue.number,
+ state: 'closed',
+ state_reason: 'not_planned'
+ });
+
+ await github.rest.issues.addLabels({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issue.number,
+ labels: ['invalid', 'auto-closed']
+ });
+
+ return;
+ }
+
+ // Count total checkboxes and checked boxes
+ const totalBoxes = (body.match(/- \[[ xX]\]/g) || []).length;
+ const checkedBoxes = (body.match(/- \[[xX]\]/g) || []).length;
+
+ // If no boxes are checked in prerequisites, add a reminder
+ if (totalBoxes > 0 && checkedBoxes === 0) {
+ const reminderMessage = [
+ '## Reminder / 提醒',
+ '',
+ '**English:**',
+ 'Please check the prerequisite boxes in the issue template to confirm you have completed the required steps.',
+ '',
+ '**中文:**',
+ '请勾选 Issue 模板中的前置条件复选框,以确认您已完成必要步骤。'
+ ].join('\n');
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issue.number,
+ body: reminderMessage
+ });
+ }
diff --git a/.github/workflows/prek.yml b/.github/workflows/prek.yml
new file mode 100644
index 0000000..8e43763
--- /dev/null
+++ b/.github/workflows/prek.yml
@@ -0,0 +1,60 @@
+name: Prek Checks
+
+on:
+ push:
+ branches: ["main", "dev"]
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ prek:
+ runs-on: ubuntu-latest
+ if: "!contains(github.event.head_commit.message, '[skip ci]')"
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
+
+ - name: Install Rust
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Install system dependencies
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update || true
+ sudo apt-get install -y \
+ libwebkit2gtk-4.1-dev \
+ build-essential \
+ libssl-dev \
+ libgtk-3-dev \
+ libayatana-appindicator3-dev \
+ librsvg2-dev \
+ pkg-config
+
+ - name: Run prek
+ id: prek
+ uses: j178/prek-action@v1
+ continue-on-error: true
+
+ - name: Check for changes
+ id: check_changes
+ if: steps.prek.outcome == 'failure'
+ run: |
+ if [ -n "$(git status --porcelain)" ]; then
+ echo "has_changes=true" >> $GITHUB_OUTPUT
+ else
+ echo "has_changes=false" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Commit fixes
+ if: steps.prek.outcome == 'failure' && steps.check_changes.outputs.has_changes == 'true'
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: "chore: apply prek auto-fixes [skip ci]"
+ commit_user_name: "hydroroll-bot"
+ commit_user_email: "bot@hydroroll.team"
+ skip_dirty_check: true
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 0000000..4005b2c
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,92 @@
+name: 'Close stale issues'
+
+on:
+ schedule:
+ - cron: '0 0 * * *' # Run daily at midnight UTC
+ workflow_dispatch:
+
+permissions:
+ issues: write
+ pull-requests: write
+
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/stale@v9
+ with:
+ # Issues
+ days-before-issue-stale: 90
+ days-before-issue-close: 7
+ stale-issue-label: 'stale'
+ exempt-issue-labels: 'pinned,enhancement,documentation'
+ stale-issue-message: |
+ ## This issue has been automatically marked as stale
+ ## 此 Issue 已被自动标记为过期
+
+ **English:**
+ This issue has had no activity for 90 days and will be closed in 7 days if no further activity occurs.
+
+ If this issue is still relevant:
+ - Comment with an update
+ - Provide additional information
+ - Confirm you're still experiencing the problem
+
+ **中文:**
+ 此 Issue 已 90 天无活动,如果继续无活动将在 7 天后关闭。
+
+ 如果此问题仍然相关:
+ - 发表评论更新状态
+ - 提供额外信息
+ - 确认您仍在遇到该问题
+
+ ---
+ *This is an automated message. To prevent closure, simply comment on this issue.*
+ close-issue-message: |
+ ## This issue has been automatically closed
+ ## 此 Issue 已被自动关闭
+
+ **English:**
+ This issue was automatically closed due to inactivity. If you're still experiencing this problem, please open a new issue with updated information.
+
+ **中文:**
+ 此 Issue 因无活动而被自动关闭。如果您仍然遇到此问题,请开启一个新的 Issue 并提供最新信息。
+
+ # Pull Requests
+ days-before-pr-stale: 60
+ days-before-pr-close: 14
+ stale-pr-label: 'stale'
+ exempt-pr-labels: 'pinned,security'
+ stale-pr-message: |
+ ## This pull request has been automatically marked as stale
+ ## 此 PR 已被自动标记为过期
+
+ **English:**
+ This pull request has had no activity for 60 days and will be closed in 14 days if no further activity occurs.
+
+ If you're still working on this:
+ - Push new commits
+ - Comment with a status update
+ - Request a review
+
+ **中文:**
+ 此 PR 已 60 天无活动,如果继续无活动将在 14 天后关闭。
+
+ 如果您仍在处理此问题:
+ - 推送新的提交
+ - 发表评论更新状态
+ - 请求审查
+ close-pr-message: |
+ ## This pull request has been automatically closed
+ ## 此 PR 已被自动关闭
+
+ **English:**
+ This pull request was automatically closed due to inactivity. Feel free to reopen if you resume work on this.
+
+ **中文:**
+ 此 PR 因无活动而被自动关闭。如果您恢复工作,请随时重新开启。
+
+ # General settings
+ operations-per-run: 100
+ remove-stale-when-updated: true
+ ascending: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 8ca056e..8bf6d2f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -10,6 +10,9 @@ on:
branches: ["main"]
workflow_dispatch:
+permissions:
+ contents: read
+
env:
CARGO_TERM_COLOR: always
@@ -42,8 +45,8 @@ jobs:
- name: Install Dependencies (Ubuntu)
if: runner.os == 'Linux' && !matrix.wayland
run: |
- sudo apt-get update
- sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
+ sudo apt-get update || true
+ sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential curl wget file libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libfuse2
- name: Install Dependencies (Arch Linux)
if: matrix.wayland
@@ -62,6 +65,27 @@ jobs:
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
+ - name: Install Node.js
+ if: github.event_name == 'workflow_dispatch'
+ uses: actions/setup-node@v4
+ with:
+ node-version: 22
+
+ - name: Install pnpm
+ if: github.event_name == 'workflow_dispatch'
+ uses: pnpm/action-setup@v2
+ with:
+ version: 9
+
+ - name: Install Frontend Dependencies
+ if: github.event_name == 'workflow_dispatch'
+ working-directory: ./ui
+ run: pnpm install
+
+ - name: Install Tauri CLI
+ if: github.event_name == 'workflow_dispatch'
+ run: cargo install tauri-cli
+
- name: Rust Cache
uses: swatinem/rust-cache@v2
with:
@@ -71,6 +95,48 @@ jobs:
working-directory: ./src-tauri
run: cargo test --verbose
- - name: Build (Dev)
+ - name: Build Rust Only (Push/PR)
+ if: github.event_name != 'workflow_dispatch'
working-directory: ./src-tauri
run: cargo build --verbose
+
+ - name: Build App (Debug)
+ if: github.event_name == 'workflow_dispatch'
+ run: cargo tauri build --debug
+
+ - name: Get Short SHA
+ if: github.event_name == 'workflow_dispatch'
+ id: slug
+ run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT
+
+ - name: Upload Artifact (Linux)
+ if: runner.os == 'Linux' && github.event_name == 'workflow_dispatch'
+ uses: actions/upload-artifact@v4
+ with:
+ name: dropout-linux-${{ matrix.wayland && 'arch' || 'ubuntu' }}-${{ steps.slug.outputs.sha8 }}
+ path: |
+ src-tauri/target/debug/bundle/appimage/*.AppImage
+ src-tauri/target/debug/bundle/deb/*.deb
+ src-tauri/target/debug/dropout
+ retention-days: 5
+
+ - name: Upload Artifact (Windows)
+ if: runner.os == 'Windows' && github.event_name == 'workflow_dispatch'
+ uses: actions/upload-artifact@v4
+ with:
+ name: dropout-windows-${{ steps.slug.outputs.sha8 }}
+ path: |
+ src-tauri/target/debug/bundle/msi/*.msi
+ src-tauri/target/debug/bundle/nsis/*.exe
+ src-tauri/target/debug/dropout.exe
+ retention-days: 5
+
+ - name: Upload Artifact (macOS)
+ if: runner.os == 'macOS' && github.event_name == 'workflow_dispatch'
+ uses: actions/upload-artifact@v4
+ with:
+ name: dropout-macos-${{ steps.slug.outputs.sha8 }}
+ path: |
+ src-tauri/target/debug/bundle/dmg/*.dmg
+ src-tauri/target/debug/bundle/macos/DropOut.app
+ retention-days: 5