feat: v0.5.2 — janela persistente, downloads paralelos e correções - #46
Conversation
Implementação própria (sem tauri-plugin-window-state, que tem bug conhecido restaurando janela maximizada no monitor errado com DPIs diferentes). Restaura só no momento de mostrar a janela (finish_splash), não durante o setup — maximizar uma janela ainda escondida força ela a ficar visível no Windows, causando um flash antes da splash cobrir. Também ignora captura/restauração de geometria inválida (janela minimizada reporta um retângulo sentinela do Windows). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…omático - launcher_profiles.json stub antes do instalador (ele exige o arquivo, herança do launcher vanilla da Mojang; sem isso falhava com "no minecraft launcher profile"). - Progresso da instalação mapeado pra texto legível em vez do Debug cru dos eventos internos da mc-launcher-core. - Console piscando durante a instalação: a crate spawna o instalador sem CREATE_NO_WINDOW; reimplementamos o spawn na nossa infra reaproveitando só o builder de args público dela. - Idioma do Minecraft detectado do Windows e aplicado no options.txt na primeira execução (nunca sobrescreve preferência já salva). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Downloads de bibliotecas do launch (vanilla + loader) e de arquivos de
modpack (Modrinth/CurseForge) rodavam sequenciais, um por vez. Agora
usam concorrência limitada via stream::buffer_unordered — 8 pra
Maven-style hosts (Mojang/Forge/NeoForge), 6 pra Modrinth/CurseForge
(hosts terceiros, mais conservador que os 16 do download de assets).
Emite eventos de progresso ("Baixando pacote...", "Resolvendo mods...")
antes do loop de download, que antes rodava mudo por vários segundos.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Estima RAM mínima/máxima com base na quantidade de mods/resource packs/shaders instalados. Aplica automaticamente ao instalar um modpack e mostra como sugestão clicável na aba de configurações da instância existente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Erro 401 do MCStat reabre o diálogo de chave com aviso claro em vez de toast genérico; ao salvar, testa a chave de verdade com um fetch antes de fechar o diálogo (fecha só se a chave funcionar). - Grid de skins responsivo por largura real (auto-fill/minmax) em vez de breakpoints fixos com salto grande no meio. - Loading da galeria centralizado na área visível (estava preso a uma altura fixa, ficava deslocado pra cima). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… visuais - Tooltip adicionado em ~15 botões de ícone que não tinham (voltar, excluir, renomear, zoom, arrastar conta, etc.) — auditoria completa contra o padrão já usado no resto do app. - Tooltip presa na tela após fechar um modal (ex: seletor de arquivo nativo) — soma listener de blur da janela ao safeguard existente. - Badge de versão do modpack/versão ilegível em hover/selecionado nas telas de instalação. - Botão voltar da sidebar de editar instância espremido pelo flexbox quando o nome da instância era longo (faltava shrink-0). - Ícone do card na tela inicial sem o fundo escuro atrás (ruim pra ícone com PNG transparente). - Botões de iniciar/parar/criar atalho na sidebar sem estado disabled durante a operação (permitia double-click/corrida). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 16 dependências Rust sem nenhum uso removidas do Cargo.toml (mc_chat, sha2, md-5, fs_extra, path-clean, tracing-subscriber, tracing-appender, toml, jsonwebtoken, crossbeam, itertools, regex, semver, async-trait, mockall, criterion); tempfile movido pra dev-dependencies (só usado em teste). - Lint nativo `unused_crate_dependencies` habilitado em lib.rs pra pegar isso automaticamente daqui pra frente — cargo clippy já não detectava dependência inteira nunca importada. - tailwindcss-animate removido do package.json (plugin do Tailwind v3, projeto já é v4 CSS-first; só tw-animate-css é importado de fato). - knip vira dependência real do projeto (antes só rodava via npx) e CI não usa mais --no-exit-code: dead-code agora quebra o gate. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Normalização de pontuação em arquivos não tocados diretamente pelas mudanças desta sessão (comentários de código, docs/*.md) — sem alteração de comportamento. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (31)
WalkthroughA versão 0.5.2 adiciona downloads concorrentes, memória sugerida, configuração automática de idioma, persistência da janela, progresso Forge/NeoForge, validação MCStat, tooltips e verificações de qualidade bloqueantes. ChangesAtualização do launcher
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 30
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/features/mods/components/InstalledContentTab.tsx (1)
155-159: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdicione nomes acessíveis aos dois botões.
tooltipPropsregistra apenas eventos de mouse. O tooltip não substituiaria-labelpara usuários de teclado e leitores de tela.
src/features/mods/components/InstalledContentTab.tsx#L155-L159: adicionearia-label="Excluir"ao botão.src/features/mods/components/ModReviewRow.tsx#L51-L56: adicionearia-label="Remover"ao botão.Mantenha os tooltips para usuários de ponteiro.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/mods/components/InstalledContentTab.tsx` around lines 155 - 159, Adicione nomes acessíveis aos botões de ação: em src/features/mods/components/InstalledContentTab.tsx#L155-L159, no botão que chama handleDelete, inclua aria-label="Excluir"; em src/features/mods/components/ModReviewRow.tsx#L51-L56, inclua aria-label="Remover" no botão correspondente. Preserve os tooltips existentes via tooltipProps.src/features/instances/components/edit-instance/ScreenshotViewerDialog.tsx (1)
141-163: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdicione
aria-labelaos botões que contêm somente ícones.
tooltipPropsregistra apenas eventos de mouse. Ele não fornece um nome acessível para leitores de tela. Adicionearia-labelaos botõesCheck,XePencil, mantendo os tooltips visuais.Correção sugerida
<Button variant="ghost" size="icon-sm" onClick={commitRename} disabled={isSavingName} + aria-label="Confirmar" {...tooltipProps('Confirmar')} > ... <Button variant="ghost" size="icon-sm" onClick={() => setIsRenaming(false)} disabled={isSavingName} + aria-label="Cancelar" {...tooltipProps('Cancelar')} > ... <Button variant="ghost" size="icon-sm" onClick={startRenaming} + aria-label="Renomear" {...tooltipProps('Renomear')} >🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/instances/components/edit-instance/ScreenshotViewerDialog.tsx` around lines 141 - 163, Adicione atributos aria-label descritivos aos Buttons que renderizam apenas os ícones Check, X e Pencil, preservando os respectivos tooltipProps existentes para feedback visual.src/features/instances/components/edit-instance/LogTab.tsx (1)
154-167: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winO tooltip pode permanecer visível após o clique.
O
onClicknas linhas 159-163 definesetShowScrollBtn(false). O botão é desmontado imediatamente.onMouseLeavenão dispara em um elemento desmontado, então o tooltip global permanece na tela até o próximoshowouhide. Oculte o tooltip dentro doonClick.🔧 Correção proposta
onClick={() => { scrollToBottom() setAutoScroll(true) setShowScrollBtn(false) + useTooltipStore.getState().hide() }}Adicione o import correspondente:
import { useTooltipStore } from '`@/stores/tooltip.store`'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/instances/components/edit-instance/LogTab.tsx` around lines 154 - 167, Update the scroll button’s onClick handler to hide the active tooltip before setShowScrollBtn(false), using the useTooltipStore symbol and its existing hide action. Add the corresponding store import and preserve the current scrolling and auto-scroll behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/04-modulos-e-dominios.md`:
- Line 57: Atualize a descrição de SuggestMemoryUseCase na tabela de Memória
para registrar que o caso de uso consulta ModRepository::find_by_instance e, em
seguida, aplica a heurística pura suggest_memory_mb. Remova a afirmação de que o
use case inteiro é “sem I/O”, preservando a caracterização da função heurística
como pura.
In `@docs/06-ipc-e-comunicacao.md`:
- Around line 7-17: Corrija a tabela de comandos separando os registros
atualmente unidos por “||” em linhas independentes, especialmente os arquivos
instance_workspace_commands.rs, minecraft_commands.rs, skin_commands.rs e
astropack_commands.rs. Preserve cada arquivo com seus respectivos comandos e
mantenha exatamente duas colunas padded: “Arquivo” e “Comandos”, com separadores
Markdown consistentes.
In `@docs/08-infraestrutura.md`:
- Line 50: Atualize a documentação sobre language.rs::ensure_default_language
para substituir o idioma fixo lang:pt_br por lang:<locale>, ou identificá-lo
claramente como exemplo; preserve a explicação de que o locale é detectado pelo
sistema e que options.txt existente não é sobrescrito.
- Line 65: Adicione testes para ensure_launcher_profile_stub cobrindo a criação
de launcher_profiles.json dentro de app_data_dir, a validação do conteúdo
esperado do stub e a preservação intacta quando o arquivo já existir.
In `@docs/11-dependencias-e-libs.md`:
- Around line 9-37: Atualize a tabela de dependências UI em
docs/11-dependencias-e-libs.md para corresponder às versões declaradas em
package.json. Preserve o prefixo ^ nas entradas tailwindcss, `@tailwindcss/vite`,
tw-animate-css, class-variance-authority, clsx e tailwind-merge, conforme
definido no manifesto.
In `@docs/12-armazenamento.md`:
- Around line 105-107: Atualize docs/12-armazenamento.md, linhas 105-107, para
descrever settings.json como o arquivo de configurações do usuário, sem afirmar
que é o único JSON do aplicativo; preserve a distinção e a descrição de
window-state.json. Ajuste também AGENTS.md, linha 443, removendo a classificação
de settings.json como único JSON e mantendo sua finalidade como configuração do
usuário.
In `@README.md`:
- Line 99: Atualize a descrição da linha de “Sugestão de RAM” no README para
indicar que a recomendação considera a quantidade total de conteúdo, incluindo
mods, resource packs e shaders, em vez de mencionar apenas mods.
In `@src-tauri/app/application/use_cases/launch_instance.rs`:
- Around line 263-338: Substitua buffer_unordered(LIBRARY_CONCURRENCY) por
buffered(LIBRARY_CONCURRENCY) nos dois fluxos de download de bibliotecas em
src-tauri/app/application/use_cases/launch_instance.rs#L263-L338 e `#L340-L377`,
preservando a ordem de entrada dos resultados que alimentam build_classpath;
nenhuma outra alteração é necessária.
- Around line 562-602: Atualize o callback de progresso em
`forge_like::install_files` para não assumir que `current_stage` começa em
`DownloadLibraries`, já que essa versão não emite `StageStarted`. Separe
bibliotecas das demais tarefas usando os dados disponíveis nos eventos, contando
apenas downloads de bibliotecas em `libraries_done` e excluindo client jar,
índice e objetos de assets do progresso de bibliotecas.
In `@src-tauri/app/application/use_cases/memory_suggestion.rs`:
- Around line 12-16: Adicione testes unitários para `suggest_memory_mb` cobrindo
as entradas 0, 1, 204 e 205, verificando os pares `(min_mb, max_mb)` retornados
e os limites de crescimento da fórmula.
In `@src-tauri/app/application/use_cases/modpack_installer/curseforge_install.rs`:
- Around line 167-169: Atualize os fluxos de instalação em curseforge_install.rs
(linhas 167-169) e modrinth_install.rs (linhas 212-214) para tratar o erro
retornado por mod_repository.save(&installed): registre o erro em log antes de
continuar, mantendo installed_count.fetch_add condicionado ao sucesso e sem
descartar falhas de persistência.
- Around line 142-155: In the mod download flow around the `done` counter and
`file_downloader::download_to_file`, move the `done.fetch_add` call and
corresponding `AstroPackEventDTO::Progress` emission to after a successful
download. Keep the existing early return for missing `resolved.download_url`
counted as currently required, and ensure progress reflects completed files
rather than downloads in progress.
In `@src-tauri/app/application/use_cases/modpack_installer/modrinth_install.rs`:
- Around line 175-183: Atualize o fluxo de instalação em modrinth_install para
incrementar done antes de cada retorno Ok(()) causado por arquivo sem URL em
file.downloads ou por caminho rejeitado por safe_join. Preserve o tratamento
atual desses arquivos ignorados e garanta que o contador alcance total.
In `@src-tauri/app/infrastructure/minecraft/language.rs`:
- Around line 9-11: Declare the kernel32 linkage explicitly on the extern block
containing GetUserDefaultLocaleName, using the appropriate Rust extern-link
attribute while preserving the existing function signature.
In `@src-tauri/app/infrastructure/modloader/forge_like/install.rs`:
- Around line 75-81: Atualize o fluxo de instalação em torno de cmd.status()
para usar cmd.output(), preservando o mesmo tratamento de sucesso e falha. Ao
falhar, extraia as últimas linhas de stderr e inclua-as na mensagem
anyhow::bail! junto com o código de saída, sem alterar o restante do fluxo.
In `@src/components/common/PageHeader.tsx`:
- Around line 16-21: Adicione nomes acessíveis aos três botões somente com
ícone: em src/components/common/PageHeader.tsx (linhas 16-21), inclua
aria-label="Voltar" no Button; em src/components/common/NumberStepperInput.tsx
(linha 70), inclua aria-label="Aumentar" no botão de incremento; e na linha 80,
inclua aria-label="Diminuir" no botão de decremento.
In `@src/features/accounts/components/AccountRow.tsx`:
- Line 57: Adicione nomes acessíveis aos controles com ícone: em
src/features/accounts/components/AccountRow.tsx:57-57, inclua
aria-label="Arrastar para reordenar" no botão de arrastar; em
src/features/accounts/components/AccountRow.tsx:98-102, inclua aria-label="Mais
opções" no botão de opções; em
src/features/instances/components/IconUploadTab.tsx:87-87, inclua
aria-label="Enviar imagem" no botão de envio; e em
src/features/instances/components/IconUploadTab.tsx:108-108, inclua
aria-label="Excluir" no botão de exclusão.
In `@src/features/instances/components/create-instance/ModpackBrowserPanel.tsx`:
- Around line 155-162: Atualize as classes do Badge renderizado no painel de
resultados para impedir o realce de hover quando o botão estiver desabilitado
durante isInstalling. Altere a lógica próxima a selected?.projectId ===
result.projectId para usar group-disabled ou condicionar as classes group-hover
a !isInstalling, preservando o destaque normal quando a instalação não estiver
em andamento.
In `@src/features/instances/components/create-instance/SourcePlaceholder.tsx`:
- Line 15: Atualize as duas descrições em SourcePlaceholder para substituir a
vírgula que separa as orações independentes por ponto e vírgula ou ponto final,
preservando o restante do texto e o significado original.
In `@src/features/instances/components/edit-instance/MemorySettingsSection.tsx`:
- Around line 28-31: Atualize o cálculo de isSuggested em MemorySettingsSection
para comparar com os valores efetivamente aplicados após os limites de
updateMinMemory/updateMaxMemory, ou ocultar o botão quando suggestedMemory
exceder totalMemoryMb. Preserve a igualdade exata para sugestões que caibam na
memória disponível e garanta que a aplicação da sugestão faça o botão
desaparecer.
In `@src/features/instances/components/edit-instance/OptionsFileEmptyState.tsx`:
- Around line 4-5: In the empty-state message in OptionsFileEmptyState, replace
the comma joining the two clauses with a period and start the instruction as a
separate sentence, preserving the existing Portuguese wording.
In `@src/features/instances/components/edit-instance/SettingsTab.tsx`:
- Around line 154-158: Atualize o callback onUseSuggested para definir minMemory
e maxMemory em uma única operação de estado, aplicando o clamp com base no par
de valores sugerido. Não chame updateMinMemory e updateMaxMemory separadamente;
preserve os valores sugeridos quando válidos e ajuste-os juntos conforme as
regras existentes de consistência.
- Line 12: Move getSuggestedMemory from ModAPI to InstanceAPI, exposing the same
Tauri command in the instances service. Update SettingsTab to use InstanceAPI
for this call, then remove the method from ModAPI and its import from
SettingsTab.
In `@src/features/instances/components/edit-instance/WorldsTab.tsx`:
- Line 126: Atualize o Button de exclusão em WorldsTab para incluir
aria-label="Excluir" juntamente com tooltipProps('Excluir'), mantendo o tooltip
existente e fornecendo um nome acessível para o ícone Trash2.
In `@src/features/instances/components/InstanceSidebar.tsx`:
- Around line 58-60: Alinhe a guarda de runAction com o estado disabled dos
botões: como a função bloqueia qualquer ação enquanto pendingKey estiver
definido, desabilite launch, stop e shortcut quando pendingKey !== null.
Atualize as condições de disabled nos controles relevantes, preservando o
comportamento de bloquear novas ações durante qualquer operação pendente.
In `@src/features/skins/components/McstatApiKeyDialog.tsx`:
- Around line 33-34: Separe as duas orações independentes na descrição exibida
por McstatApiKeyDialog, substituindo a vírgula entre “API key própria” e “ela
não vem embutida no launcher” por ponto ou ponto e vírgula, sem alterar o
restante do texto.
- Around line 7-10: Trate a rejeição de submitMcstatKey nas chamadas de onClick
e onKeyDown usadas por SingleFieldDialog, aguardando ou capturando a Promise
retornada para evitar rejeições não tratadas. Mantenha o diálogo aberto e
preserve o controle existente de isSubmitting quando o envio falhar.
In `@src/features/skins/pages/SkinsPage.tsx`:
- Around line 115-117: Atualize submitMcstatKey para validar a chave candidata
via SkinAPI.search antes de chamar SettingsAPI.update; persista o novo valor
somente após uma resposta válida. Em caso de 401 ou falha de rede, mantenha a
chave anterior, atualize mcstatKeyInvalid ou exiba o toast conforme o fluxo
existente, sem salvar a chave inválida.
In `@src/features/skins/pages/useSkinsBrowser.ts`:
- Line 159: Ignore stale gallery request failures before updating the UI: at
src/features/skins/pages/useSkinsBrowser.ts:159-159, apply the same
galleryRequestIdRef check used in then() before calling handleSkinsError; at
src/features/skins/pages/useSkinsBrowser.ts:206-206, associate loadMore with the
active gallery source, sort, and model epoch/key and skip error handling when
any has changed.
- Around line 125-131: Atualize o tratamento de erro no fluxo de validação de
chave em useSkinsBrowser, especialmente no catch após SkinAPI.search: quando
SettingsAPI.update já tiver concluído e a busca falhar, exiba uma mensagem
indicando falha na validação, não no salvamento. Preserve o tratamento de
isUnauthorized e relance o erro como atualmente.
---
Outside diff comments:
In `@src/features/instances/components/edit-instance/LogTab.tsx`:
- Around line 154-167: Update the scroll button’s onClick handler to hide the
active tooltip before setShowScrollBtn(false), using the useTooltipStore symbol
and its existing hide action. Add the corresponding store import and preserve
the current scrolling and auto-scroll behavior.
In `@src/features/instances/components/edit-instance/ScreenshotViewerDialog.tsx`:
- Around line 141-163: Adicione atributos aria-label descritivos aos Buttons que
renderizam apenas os ícones Check, X e Pencil, preservando os respectivos
tooltipProps existentes para feedback visual.
In `@src/features/mods/components/InstalledContentTab.tsx`:
- Around line 155-159: Adicione nomes acessíveis aos botões de ação: em
src/features/mods/components/InstalledContentTab.tsx#L155-L159, no botão que
chama handleDelete, inclua aria-label="Excluir"; em
src/features/mods/components/ModReviewRow.tsx#L51-L56, inclua
aria-label="Remover" no botão correspondente. Preserve os tooltips existentes
via tooltipProps.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 64a55475-741c-47dd-b5c8-46162d9aa171
⛔ Files ignored due to path filters (6)
docs/screenshots/demo.gifis excluded by!**/*.gifdocs/screenshots/editor.pngis excluded by!**/*.pngdocs/screenshots/home.pngis excluded by!**/*.pngdocs/screenshots/skins.pngis excluded by!**/*.pngpackage-lock.jsonis excluded by!**/package-lock.jsonsrc-tauri/Cargo.lockis excluded by!**/*.lock,!**/*.lock
📒 Files selected for processing (135)
.github/releases/v0.5.2.md.github/workflows/quality-gate.ymlAGENTS.mdREADME.mddocs/01-visao-geral.mddocs/02-arquitetura.mddocs/04-modulos-e-dominios.mddocs/05-padroes-e-boas-praticas.mddocs/06-ipc-e-comunicacao.mddocs/08-infraestrutura.mddocs/11-dependencias-e-libs.mddocs/12-armazenamento.mdknip.jsonpackage.jsonsrc-tauri/Cargo.tomlsrc-tauri/app/application/dto/instance_dto.rssrc-tauri/app/application/dto/mod.rssrc-tauri/app/application/dto/mod_dto.rssrc-tauri/app/application/dto/skin_dto.rssrc-tauri/app/application/use_cases/astropack_service/astropack_import.rssrc-tauri/app/application/use_cases/astropack_service/content.rssrc-tauri/app/application/use_cases/delete_instance.rssrc-tauri/app/application/use_cases/duplicate_instance.rssrc-tauri/app/application/use_cases/instance_workspace/config_files.rssrc-tauri/app/application/use_cases/instance_workspace/notes.rssrc-tauri/app/application/use_cases/instance_workspace/shortcuts.rssrc-tauri/app/application/use_cases/launch_instance.rssrc-tauri/app/application/use_cases/memory_suggestion.rssrc-tauri/app/application/use_cases/mod.rssrc-tauri/app/application/use_cases/mod_manager.rssrc-tauri/app/application/use_cases/modpack_installer.rssrc-tauri/app/application/use_cases/modpack_installer/curseforge_install.rssrc-tauri/app/application/use_cases/modpack_installer/modrinth_install.rssrc-tauri/app/application/use_cases/playtime_service.rssrc-tauri/app/application/use_cases/skin_browser.rssrc-tauri/app/bootstrap/setup.rssrc-tauri/app/domain/entities/installed_mod.rssrc-tauri/app/domain/repositories/playtime_repository.rssrc-tauri/app/infrastructure/cli.rssrc-tauri/app/infrastructure/curseforge/client.rssrc-tauri/app/infrastructure/discord/rpc.rssrc-tauri/app/infrastructure/downloader/progress.rssrc-tauri/app/infrastructure/filesystem/safe_path.rssrc-tauri/app/infrastructure/filesystem/shortcut.rssrc-tauri/app/infrastructure/filesystem/shortcut/icon.rssrc-tauri/app/infrastructure/filesystem/shortcut/powershell.rssrc-tauri/app/infrastructure/minecraft/language.rssrc-tauri/app/infrastructure/minecraft/mod.rssrc-tauri/app/infrastructure/minecraft/servers_dat/write.rssrc-tauri/app/infrastructure/mod.rssrc-tauri/app/infrastructure/modloader/forge_like.rssrc-tauri/app/infrastructure/modloader/forge_like/command.rssrc-tauri/app/infrastructure/modloader/forge_like/install.rssrc-tauri/app/infrastructure/modloader/liteloader.rssrc-tauri/app/infrastructure/modloader/profile.rssrc-tauri/app/infrastructure/modrinth/client.rssrc-tauri/app/infrastructure/modrinth/client/dto.rssrc-tauri/app/infrastructure/modrinth/mrpack.rssrc-tauri/app/infrastructure/playermc/client.rssrc-tauri/app/infrastructure/process/launcher.rssrc-tauri/app/infrastructure/process/manager.rssrc-tauri/app/infrastructure/window_state.rssrc-tauri/app/presentation/commands/astropack_commands.rssrc-tauri/app/presentation/commands/discord_commands.rssrc-tauri/app/presentation/commands/instance_workspace_commands/shortcut_commands.rssrc-tauri/app/presentation/commands/minecraft_commands.rssrc-tauri/app/presentation/commands/mod_commands.rssrc-tauri/app/presentation/commands/splash_commands.rssrc-tauri/app/presentation/state/app_state.rssrc-tauri/src/lib.rssrc-tauri/src/main.rssrc-tauri/tauri.conf.jsonsrc/App.tsxsrc/components/common/CodeEditor.tsxsrc/components/common/CursorTooltip.tsxsrc/components/common/MarkdownBody.tsxsrc/components/common/NumberStepperInput.tsxsrc/components/common/PageHeader.tsxsrc/components/common/SidebarNav.tsxsrc/components/layout/ChangelogDialog.tsxsrc/components/layout/TopBar.tsxsrc/components/ui/scroll-area.tsxsrc/features/accounts/components/AccountRow.tsxsrc/features/instances/components/ConfirmDeleteFolderDialog.tsxsrc/features/instances/components/IconPickerButton.tsxsrc/features/instances/components/IconUploadTab.tsxsrc/features/instances/components/InstanceCard.tsxsrc/features/instances/components/InstanceSidebar.tsxsrc/features/instances/components/InstancesBackground.tsxsrc/features/instances/components/create-instance/ModpackBrowserPanel.tsxsrc/features/instances/components/create-instance/ModpackVersionPicker.tsxsrc/features/instances/components/create-instance/SourcePlaceholder.tsxsrc/features/instances/components/edit-instance/ConfigFilesTab.tsxsrc/features/instances/components/edit-instance/LogTab.tsxsrc/features/instances/components/edit-instance/MemorySettingsSection.tsxsrc/features/instances/components/edit-instance/NotesTab.tsxsrc/features/instances/components/edit-instance/OptionsFileEmptyState.tsxsrc/features/instances/components/edit-instance/ResizableImageExtension.tsxsrc/features/instances/components/edit-instance/ScreenshotViewerDialog.tsxsrc/features/instances/components/edit-instance/ScreenshotZoomControls.tsxsrc/features/instances/components/edit-instance/ServersTab.tsxsrc/features/instances/components/edit-instance/SettingsTab.tsxsrc/features/instances/components/edit-instance/WorldsTab.tsxsrc/features/instances/hooks/useInstancesPage.tssrc/features/instances/lib/instance-actions.tssrc/features/instances/pages/InstancesPage.tsxsrc/features/mods/components/InstalledContentTab.tsxsrc/features/mods/components/ModBrowserDialog.tsxsrc/features/mods/components/ModReviewRow.tsxsrc/features/mods/components/useModBrowser.tssrc/features/mods/components/useReviewEntries.tssrc/features/mods/services/mod.api.tssrc/features/skins/components/McstatApiKeyDialog.tsxsrc/features/skins/components/SkinCard.tsxsrc/features/skins/components/SkinDetailDialog.tsxsrc/features/skins/components/SkinViewer3D.tsxsrc/features/skins/components/useSkinDetail.tssrc/features/skins/lib/thumbnailQueue.tssrc/features/skins/lib/thumbnailRenderer.tssrc/features/skins/pages/SkinsPage.tsxsrc/features/skins/pages/useSkinsBrowser.tssrc/hooks/useBlockBrowserNavigation.tssrc/hooks/useBlockNativeContextMenu.tssrc/hooks/useDiscordPresence.tssrc/lib/icon-src.tssrc/lib/keybind-labels.tssrc/lib/keybind-utils.tssrc/lib/minecraft-option-metadata.tssrc/lib/tooltip.tssrc/stores/import-astropack.store.tssrc/stores/launch.store.tssrc/stores/tooltip.store.tssrc/types/instance.tssrc/types/mods.tssrc/types/skins.ts
💤 Files with no reviewable changes (1)
- knip.json
| | Arquivo | Comandos | | ||
| | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || `instance_commands.rs` | `list_instances`, `create_instance`, `update_instance`, `delete_instance`, `duplicate_instance`, `move_instance_to_folder`, `reorder_instances` | | ||
| | `folder_commands.rs` | `list_folders`, `create_folder`, `update_folder`, `delete_folder`, `reorder_folders` | | ||
| | `instance_workspace_commands.rs` | 25 comandos: log, notas, arquivos de config, mundos, servers, screenshots, atalhos — ex.: `read_instance_log`, `list_instance_notes`, `write_instance_note`, `list_instance_config_files`, `write_instance_config_file`, `list_instance_worlds`, `delete_instance_world`, `list_instance_servers`, `add_instance_server`, `list_instance_screenshots`, `save_instance_screenshot_as`, `list_instance_shortcuts`, `toggle_instance_shortcut`, `refresh_instance_shortcut_icon` || `minecraft_commands.rs` | `list_minecraft_versions` (async), `launch_instance` (async), `stop_instance`, `cancel_launch`, `get_total_system_memory_mb`, `list_audio_output_devices`, `take_pending_launch` | | ||
| | `account_commands.rs` | `list_accounts`, `create_account`, `update_account`, `delete_account`, `set_default_account`, `reorder_accounts` | | ||
| | `mod_commands.rs` | `search_mods`, `get_mod_versions`, `get_mod_project` (async), `install_mod` (async), `install_custom_mod`, `list_instance_mods`, `get_suggested_memory`, `set_instance_mod_enabled`, `delete_instance_mod`, `install_modrinth_modpack`, `install_curseforge_modpack` (async), `cancel_modpack_install` | | ||
| | `skin_commands.rs` | `search_skins`, `get_skin`, `download_skin`, `fetch_skin_texture_base64` (async) || `astropack_commands.rs` | `preview_astropack`, `get_astropack_export_summary`, `export_instance`, `import_astropack` (async), `take_pending_astropack_path` | | ||
| | `playtime_commands.rs` | `get_playtime_summary` | | ||
| | `settings_commands.rs` | `get_settings`, `update_settings` | | ||
| | `discord_commands.rs` | `discord_set_presence` | | ||
| | `custom_icon_commands.rs` | `list_custom_icons`, `save_custom_icon`, `delete_custom_icon` | |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Corrija a estrutura da tabela de comandos.
As Lines [8], [10] e [13] usam || para juntar registros. O cabeçalho possui duas colunas, portanto o Markdown cria células extras e pode combinar arquivos diferentes na mesma linha.
Separe cada arquivo em uma linha própria. Use exatamente duas colunas padded: Arquivo e Comandos.
As per coding guidelines: tabelas em Markdown devem ser padded.
🧰 Tools
🪛 LanguageTool
[locale-violation] ~10-~10: “servers” é um estrangeirismo. É preferível dizer “servidores”.
Context: ...log, notas, arquivos de config, mundos, servers, screenshots, atalhos — ex.: `read_inst...
(PT_BARBARISMS_REPLACE_SERVERS)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/06-ipc-e-comunicacao.md` around lines 7 - 17, Corrija a tabela de
comandos separando os registros atualmente unidos por “||” em linhas
independentes, especialmente os arquivos instance_workspace_commands.rs,
minecraft_commands.rs, skin_commands.rs e astropack_commands.rs. Preserve cada
arquivo com seus respectivos comandos e mantenha exatamente duas colunas padded:
“Arquivo” e “Comandos”, com separadores Markdown consistentes.
Source: Coding guidelines
|
|
||
| - **Fabric/Quilt**: consomem API REST (`meta.fabricmc.net/v2`, `meta.quiltmc.org/v3`) que já devolve um `LoaderProfile` pronto (main class + libraries), sem precisar rodar instalador. | ||
| - **Forge/NeoForge**: baixam e executam o jar instalador oficial do loader (`java -jar installer.jar --installClient <dir>`) via `mc_launcher_core`, exigindo o JSON da versão vanilla já em disco (`ensure_vanilla_json_on_disk`) para o merge `inheritsFrom` funcionar. Usa `mc_launcher_core::command::builder::build_launch_command` para o comando final, não `process/launcher.rs`. | ||
| - **Forge/NeoForge**: baixam e executam o jar instalador oficial do loader (`java -jar installer.jar --installClient <dir>`) via `mc_launcher_core`, exigindo o JSON da versão vanilla já em disco (`ensure_vanilla_json_on_disk`) para o merge `inheritsFrom` funcionar. Desde v0.5.2 também exige o stub `launcher_profiles.json` (`ensure_launcher_profile_stub`) — o instalador aborta com "There is no minecraft launcher profile" se o arquivo não existir no diretório de dados (herança do launcher vanilla da Mojang). Usa `mc_launcher_core::command::builder::build_launch_command` para o comando final, não `process/launcher.rs`. O progresso da instalação vem de `mc_launcher_core::progress::ProgressEvent` e é mapeado para labels PT-BR + progresso real de bibliotecas em `launch_instance.rs::run_forge_like`. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -C 6 \
'ensure_launcher_profile_stub|launcher_profiles\.json|There is no minecraft launcher profile' \
src-tauri || true
rg -n -C 6 \
'ensure_vanilla_json_on_disk|run_forge_like' \
src-tauri || trueRepository: kauafpssx/AstroLauncher
Length of output: 11891
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- implementação do stub ---'
sed -n '1,90p' src-tauri/app/infrastructure/modloader/forge_like/install.rs
printf '%s\n' '--- chamadas e fluxo de instalação ---'
sed -n '500,565p' src-tauri/app/application/use_cases/launch_instance.rs
printf '%s\n' '--- testes e referências adicionais ---'
rg -n -C 8 \
'ensure_launcher_profile_stub|launcher_profiles\.json|There is no minecraft launcher profile|v0\.5\.2' \
--glob '*.rs' --glob '*.md' .
printf '%s\n' '--- trecho da documentação ---'
sed -n '55,72p' docs/08-infraestrutura.mdRepository: kauafpssx/AstroLauncher
Length of output: 50381
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- arquivos de teste do forge_like ---'
git ls-files | rg 'forge_like/.*/tests|forge_like/tests|forge_like.*test'
printf '%s\n' '--- testes relacionados ---'
rg -n -C 5 \
'ensure_launcher_profile_stub|launcher_profiles\.json|ensure_vanilla_json_on_disk|run_forge_like' \
src-tauri/app --glob '*test*.rs' --glob 'tests/**/*.rs' || true
printf '%s\n' '--- diretório usado no fluxo ---'
rg -n -C 3 \
'ensure_launcher_profile_stub\(&app_data_dir\)|run_installer\([^;]*&app_data_dir' \
src-tauri/app/application/use_cases/launch_instance.rsRepository: kauafpssx/AstroLauncher
Length of output: 831
Adicione testes para ensure_launcher_profile_stub.
Cubra a criação de <app_data_dir>/launcher_profiles.json, o conteúdo do stub e a preservação de um arquivo existente. Não há testes relacionados no repositório.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~65-~65: Se é uma abreviatura, falta um ponto. Se for uma expressão, coloque entre aspas.
Context: ...tam o jar instalador oficial do loader (java -jar installer.jar --installClient <dir>) via mc_launcher_core, exigindo o J...
(ABREVIATIONS_PUNCTUATION)
[uncategorized] ~65-~65: Pontuação duplicada
Context: ...nça do launcher vanilla da Mojang). Usa mc_launcher_core::command::builder::build_launch_command ...
(DOUBLE_PUNCTUATION_XML)
[uncategorized] ~65-~65: Pontuação duplicada
Context: ...r.rs. O progresso da instalação vem de mc_launcher_core::progress::ProgressEvent` e é mapeado par...
(DOUBLE_PUNCTUATION_XML)
[uncategorized] ~65-~65: Pontuação duplicada
Context: ...T-BR + progresso real de bibliotecas em launch_instance.rs::run_forge_like. ## 8.6 Filesystem ```...
(DOUBLE_PUNCTUATION_XML)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/08-infraestrutura.md` at line 65, Adicione testes para
ensure_launcher_profile_stub cobrindo a criação de launcher_profiles.json dentro
de app_data_dir, a validação do conteúdo esperado do stub e a preservação
intacta quando o arquivo já existir.
| | Biblioteca | Versão | Finalidade | | ||
| | -------------------------------- | ----------------------- | ------------------------------------------------------ | | ||
| | `tauri` | 2.11.3 | Framework desktop nativo (feature `protocol-asset`) | | ||
| | `tauri-build` | 2.6.3 | Build script do Tauri | | ||
| | `tauri-plugin-dialog` | 2.7.2 | Diálogos nativos | | ||
| | `tauri-plugin-fs` | 2.5.1 | Acesso ao sistema de arquivos | | ||
| | `tauri-plugin-shell` | 2.3.5 | Spawn de processos | | ||
| | `tauri-plugin-clipboard-manager` | 2 | Área de transferência | | ||
| | `tauri-plugin-updater` | 2.10.1 | Auto-update in-app | | ||
| | `tauri-plugin-process` | 2.3.1 | Controle do processo do próprio app (restart/exit) | | ||
| | `tauri-plugin-single-instance` | 2 | Instância única + repasse de argv (atalhos/.astropack) | | ||
| | `tauri-plugin-log` | 2 | Logging integrado ao Tauri | | ||
| | `serde` / `serde_json` | 1.0 | Serialização/deserialização | | ||
| | `thiserror` | 2.0.19 | Erros tipados | | ||
| | `anyhow` | 1.0.104 | Erros contextuais | | ||
| | `tokio` | 1.53.1 (feature `full`) | Runtime assíncrono | | ||
| | `log` | 0.4 | Fachada de logging | | ||
|
|
||
| ### Minecraft | ||
|
|
||
| | Biblioteca | Versão | Finalidade | | ||
| | ------------------ | ------------------ | ------------------------------------------------------------------------------ | | ||
| | `mc-launcher-core` | 0.1.2 | Building blocks de launcher (Forge/NeoForge installer, launch command builder) | | ||
| | `mc_chat` | 0.3.0 | Parsing de chat formatado do Minecraft | | ||
| | `uuid` | 1.20.0 (v4, serde) | UUIDs de contas offline | | ||
|
|
||
| Não existe crate `mc-versions` — parsing de tipos de versão é feito com os DTOs próprios (`VersionDTO`, `version_meta.rs`). | ||
|
|
||
| `mc_chat` foi **removido** na v0.5.2 (sem uso real — o lint `unused_crate_dependencies` pega dependências órfãs no CI). | ||
|
|
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -C 2 \
'tauri-plugin-single-instance|mc-launcher-core|reqwest|sha2|md-5|fs_extra|path-clean|tempfile|tracing-subscriber|tracing-appender|toml|jsonwebtoken|crossbeam|itertools|regex|semver|async-trait|mockall|criterion|tailwindcss-animate|tw-animate-css|lucide-react|radix-ui|knip' \
src-tauri/Cargo.toml package.jsonRepository: kauafpssx/AstroLauncher
Length of output: 1913
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' '--- docs ---'
cat -n docs/11-dependencias-e-libs.md | sed -n '1,180p'
printf '%s\n' '--- Cargo.toml ---'
cat -n src-tauri/Cargo.toml | sed -n '1,140p'
printf '%s\n' '--- package.json ---'
cat -n package.json | sed -n '1,120p'
printf '%s\n' '--- relevant configuration references ---'
rg -n -C 3 \
'unused_crate_dependencies|knip|unused.*depend|quality|lint|cargo|format:check|build' \
.github Cargo.toml src-tauri package.json 2>/dev/null || trueRepository: kauafpssx/AstroLauncher
Length of output: 50381
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
import json
import re
from pathlib import Path
docs = Path("docs/11-dependencias-e-libs.md").read_text()
package = json.loads(Path("package.json").read_text())
cargo = Path("src-tauri/Cargo.toml").read_text()
# Extract direct Cargo dependency declarations and npm dependency declarations.
cargo_names = set()
in_deps = False
for line in cargo.splitlines():
stripped = line.strip()
if stripped == "[dependencies]":
in_deps = True
continue
if stripped.startswith("[") and stripped != "[dependencies]":
in_deps = False
if in_deps and re.match(r"^[A-Za-z0-9_-]+\s*=", stripped):
cargo_names.add(stripped.split("=", 1)[0].strip())
npm_names = set(package["dependencies"]) | set(package["devDependencies"])
print("--- direct dependency presence ---")
for name in [
"tauri-plugin-single-instance", "mc-launcher-core", "reqwest", "sha1",
"sha2", "md-5", "fs_extra", "path-clean", "tempfile",
"tracing-subscriber", "tracing-appender", "toml", "jsonwebtoken",
"crossbeam", "itertools", "regex", "semver", "async-trait",
"mockall", "criterion",
]:
print(f"{name}: cargo={name in cargo_names}; cargo_dev={name == 'tempfile' and '[dev-dependencies]' in cargo}; npm={name in npm_names}")
print("--- frontend manifest declarations versus documented UI table ---")
for name in ["tailwindcss", "`@tailwindcss/vite`", "tw-animate-css", "class-variance-authority", "clsx", "tailwind-merge", "lucide-react", "radix-ui", "shadcn"]:
raw = next(
(line.strip().split(":", 1)[1].rstrip(",").strip()
for line in Path("package.json").read_text().splitlines()
if line.strip().startswith(f'"{name}":')),
None,
)
print(f"{name}: manifest={raw}")
PY
printf '%s\n' '--- lint configuration ---'
cat -n src-tauri/src/lib.rs | sed -n '1,12p'
cat -n src-tauri/src/main.rs | sed -n '1,10p'Repository: kauafpssx/AstroLauncher
Length of output: 2745
Alinhe as versões da tabela UI com o package.json.
Mantenha o prefixo ^ em tailwindcss, @tailwindcss/vite, tw-animate-css, class-variance-authority, clsx e tailwind-merge, pois o manifesto declara faixas de versão.
🧰 Tools
🪛 LanguageTool
[grammar] ~12-~12: Possível erro de concordância.
Context: ... | 2.6.3 | Build script do Tauri ...
(GENERAL_GENDER_AGREEMENT_ERRORS)
[locale-violation] ~16-~16: “manager” é um estrangeirismo. É preferível dizer “gestor”, “gerente” ou “treinador”.
Context: ... | | tauri-plugin-clipboard-manager | 2 | Área de tr...
(PT_BARBARISMS_REPLACE_MANAGER)
[misspelling] ~17-~17: Esta é uma palavra só.
Context: ...` | 2.10.1 | Auto-update in-app ...
(AUTO)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/11-dependencias-e-libs.md` around lines 9 - 37, Atualize a tabela de
dependências UI em docs/11-dependencias-e-libs.md para corresponder às versões
declaradas em package.json. Preserve o prefixo ^ nas entradas tailwindcss,
`@tailwindcss/vite`, tw-animate-css, class-variance-authority, clsx e
tailwind-merge, conforme definido no manifesto.
| invalidKey?: boolean | ||
| onOpenChange: (open: boolean) => void | ||
| onSaved: (key: string) => void | ||
| onSubmit: (key: string) => Promise<void> | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -C 8 \
'SingleFieldDialog|submitLoadingLabel|onSubmit|isPending|await' \
src --glob '*.{ts,tsx}'Repository: kauafpssx/AstroLauncher
Length of output: 50380
🏁 Script executed:
#!/bin/bash
set -euo pipefail
dialog_file="$(fd -t f 'SingleFieldDialog' src | head -n 1)"
printf '%s\n' "=== $dialog_file ==="
wc -l "$dialog_file"
cat -n "$dialog_file"
printf '%s\n' '=== Mcstat references ==='
rg -n -C 12 'submitMcstatKey|mcstatKeyInvalid|McstatApiKeyDialog' src/features/skinsRepository: kauafpssx/AstroLauncher
Length of output: 17308
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '=== useSkinsBrowser submit flow ==='
cat -n src/features/skins/pages/useSkinsBrowser.ts | sed -n '80,140p'
printf '%s\n' '=== McstatApiKeyDialog ==='
cat -n src/features/skins/components/McstatApiKeyDialog.tsx
printf '%s\n' '=== Dialog primitive handlers ==='
rg -n -C 6 'onPointerDownOutside|onEscapeKeyDown|DialogContent|onOpenChange' src/components/ui/dialog.tsxRepository: kauafpssx/AstroLauncher
Length of output: 5369
Trate a rejeição de handleSubmit em SingleFieldDialog.
O componente aguarda onSubmit, mantém o diálogo aberto e libera isSubmitting. Porém, as chamadas em onClick e onKeyDown não tratam a Promise rejeitada por submitMcstatKey, o que gera uma rejeição não tratada. Adicione um tratamento de erro sem fechar o diálogo.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/skins/components/McstatApiKeyDialog.tsx` around lines 7 - 10,
Trate a rejeição de submitMcstatKey nas chamadas de onClick e onKeyDown usadas
por SingleFieldDialog, aguardando ou capturando a Promise retornada para evitar
rejeições não tratadas. Mantenha o diálogo aberto e preserve o controle
existente de isSubmitting quando o envio falhar.
| invalidKey={mcstatKeyInvalid} | ||
| onOpenChange={setMcstatKeyDialogOpen} | ||
| onSaved={(key) => { | ||
| setMcstatApiKey(key) | ||
| setSource('mcstat') | ||
| }} | ||
| onSubmit={submitMcstatKey} |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Valide a chave antes de persistir o novo valor.
O fluxo de submitMcstatKey chama SettingsAPI.update antes de SkinAPI.search. Se a busca retornar 401 ou falhar por rede, o código apenas atualiza mcstatKeyInvalid ou exibe um toast. A chave candidata já substituiu a chave anterior nas configurações.
Valide a chave sem persistência. Salve-a somente após uma resposta válida. Em caso de falha, preserve a chave anterior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/skins/pages/SkinsPage.tsx` around lines 115 - 117, Atualize
submitMcstatKey para validar a chave candidata via SkinAPI.search antes de
chamar SettingsAPI.update; persista o novo valor somente após uma resposta
válida. Em caso de 401 ou falha de rede, mantenha a chave anterior, atualize
mcstatKeyInvalid ou exiba o toast conforme o fluxo existente, sem salvar a chave
inválida.
- classpath do launch deixava de ser determinístico (buffer_unordered não preserva ordem de conclusão); troca pra buffered em ambos os loops de biblioteca, mesma concorrência, ordem de entrada preservada - install_files do Forge/NeoForge nunca emite StageStarted (verificado na crate) — o gate por "stage atual" nunca mudava do default e varria todo mundo (client jar, milhares de assets) pro balde de "biblioteca"; agora classifica cada task pelo próprio path de destino, capturado no TaskStarted - contador de progresso do CurseForge avançava antes do download terminar (na resolução de metadata); move pra depois do download - arquivos ignorados no Modrinth (sem URL, path rejeitado) não incrementavam o contador — progresso nunca batia 100% - erro de persistência do InstalledMod era descartado silenciosamente nos dois instaladores — agora loga um warn - ~15 aria-label em botões só-ícone pra leitor de tela (tooltip não substitui nome acessível) - tooltip do LogTab reforçada com hide explícito no click (defesa extra além do safeguard global já existente) - badge de versão no ModpackBrowserPanel reagia a hover mesmo com botão desabilitado durante instalação - MemorySettingsSection: botão de sugestão ficava preso na tela pra sempre quando a sugestão excedia a RAM total (nunca batia o valor aplicado, que fica clampado) - SettingsTab: onUseSuggested aplicava valores errados por causa de closure obsoleta entre updateMinMemory/updateMaxMemory — agora seta os dois juntos; getSuggestedMemory movido de ModAPI pra InstanceAPI (é comando de instância, não de mod) - InstanceSidebar: guarda de pendingKey bloqueia qualquer ação mas só desabilitava visualmente o botão específico — agora desabilita todos os botões guardados enquanto qualquer um estiver pendente - SingleFieldDialog: rejeição não tratada quando onSubmit falha (handleSubmit não tinha catch, virava unhandled rejection) - fluxo de validação da chave MCStat: reverte pro valor anterior no settings.json se a chave nova falhar na validação (evita deixar uma chave inválida persistida); mensagem de erro agora distingue falha de salvar vs. falha de validar - useSkinsBrowser: catch da galeria não checava se a requisição ainda era a atual antes de reagir ao erro; loadMore ganhou o mesmo guard - language.rs: linkage explícito (#[link(name = "kernel32")]) no extern block - forge_like/install.rs: captura stderr do instalador e inclui no erro em vez de só o código de saída - 4 testes unitários novos pra suggest_memory_mb (limites da heurística) - pequenos ajustes de doc (locale de exemplo, settings.json não é mais o único JSON, sugestão de RAM cobre todo conteúdo instalado) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
📝 Descrição
Leva de correções e melhorias pro ciclo 0.5.2: persistência de estado da janela, downloads em paralelo pra modpacks/bibliotecas, sugestão de memória, correções no fluxo Forge/NeoForge, tratamento de chave inválida do MCStat e diversos ajustes de UI/tooltip. Fecha o ciclo com bump de versão, release notes e GIF de demonstração no README.
🧩 Mudanças
Funcionalidade nova
Correção de bug
Refatoração
Documentação
Dependências / CI
Persiste posição/tamanho/monitor/maximizada da janela principal entre sessões (implementação própria, evita bug conhecido do plugin oficial em setups multi-monitor com DPI diferente)
Corrige flash da janela principal antes da splash aparecer
Corrige instalação do Forge/NeoForge (
launcher_profiles.jsonausente, progresso ilegível, console piscando)Idioma do Minecraft detectado automaticamente do Windows na primeira execução
Downloads em paralelo pra bibliotecas do launch e arquivos de modpack (Modrinth/CurseForge), com concorrência limitada por host
Sugestão de memória (RAM) pra instâncias criadas a partir de modpack, baseada na quantidade de conteúdo instalado
Chave de API do MCStat inválida agora reabre o diálogo com aviso e testa a chave antes de fechar
Grid de skins responsivo, loading centralizado
~15 tooltips ausentes adicionados, tooltip presa após fechar modal corrigida, badge de versão ilegível corrigido, botões sem estado disabled corrigidos, outros ajustes visuais menores
16 dependências Rust mortas removidas + lint
unused_crate_dependencieshabilitado;tailwindcss-animateremovido;knipagora bloqueia o CIBump de versão pra
0.5.2, release notes, GIF/screenshots novos no README✅ Checklist
mainatualizadathiserror, código em inglês)npm run lintpassou sem errosnpm run build(typecheck) passou.github/releases/v0.5.2.md)🖼️ Evidências
GIF de demonstração e screenshots adicionados em
docs/screenshots/(referenciados no README atualizado).🔗 Issues relacionadas
—
Summary by CodeRabbit
Novos Recursos
Correções