Skip to content

feat: v0.5.2 — janela persistente, downloads paralelos e correções - #46

Merged
kauafpssx merged 10 commits into
mainfrom
feat/v0.5.2
Aug 7, 2026
Merged

kauafpssx merged 10 commits into
mainfrom
feat/v0.5.2

Conversation

@kauafpssx

@kauafpssx kauafpssx commented Aug 7, 2026 •

Copy link
Copy Markdown
Owner

📝 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.json ausente, 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_dependencies habilitado; tailwindcss-animate removido; knip agora bloqueia o CI

  • Bump de versão pra 0.5.2, release notes, GIF/screenshots novos no README

✅ Checklist

  • Branch criada a partir da main atualizada
  • Código segue os padrões do projeto (máx. 200 linhas por arquivo, erros com thiserror, código em inglês)
  • npm run lint passou sem erros
  • npm run build (typecheck) passou
  • Testei manualmente o fluxo alterado
  • Atualizei as notas de release (.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

    • Sugestão automática de memória para modpacks, com aplicação rápida nas configurações.
    • Downloads paralelos e progresso detalhado na instalação de modpacks e Forge/NeoForge.
    • Detecção automática do idioma do Minecraft.
    • Restauração da posição, tamanho e estado da janela.
    • Validação de chaves MCStat inválidas ou expiradas.
    • Novos tooltips, rótulos acessíveis e melhorias visuais na interface.
  • Correções

    • Ações principais e atalhos agora evitam cliques duplicados.
    • Instaladores recuperam falhas com cancelamento e rollback adequados.

kauafpssx and others added 9 commits August 7, 2026 01:00
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>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d376a8ce-bb4e-45bf-85b8-3e94bf335acc

📥 Commits

Reviewing files that changed from the base of the PR and between 5405bd0 and b0af8f9.

📒 Files selected for processing (31)
  • AGENTS.md
  • README.md
  • docs/04-modulos-e-dominios.md
  • docs/08-infraestrutura.md
  • docs/12-armazenamento.md
  • src-tauri/app/application/use_cases/launch_instance.rs
  • src-tauri/app/application/use_cases/memory_suggestion.rs
  • src-tauri/app/application/use_cases/modpack_installer/curseforge_install.rs
  • src-tauri/app/application/use_cases/modpack_installer/modrinth_install.rs
  • src-tauri/app/application/use_cases/tests/memory_suggestion_tests.rs
  • src-tauri/app/infrastructure/minecraft/language.rs
  • src-tauri/app/infrastructure/modloader/forge_like/install.rs
  • src/components/common/NumberStepperInput.tsx
  • src/components/common/PageHeader.tsx
  • src/components/common/SingleFieldDialog.tsx
  • src/features/accounts/components/AccountRow.tsx
  • src/features/instances/components/IconUploadTab.tsx
  • src/features/instances/components/InstanceSidebar.tsx
  • src/features/instances/components/create-instance/ModpackBrowserPanel.tsx
  • src/features/instances/components/create-instance/SourcePlaceholder.tsx
  • src/features/instances/components/edit-instance/LogTab.tsx
  • src/features/instances/components/edit-instance/MemorySettingsSection.tsx
  • src/features/instances/components/edit-instance/OptionsFileEmptyState.tsx
  • src/features/instances/components/edit-instance/ScreenshotViewerDialog.tsx
  • src/features/instances/components/edit-instance/SettingsTab.tsx
  • src/features/instances/components/edit-instance/WorldsTab.tsx
  • src/features/instances/services/instance.api.ts
  • src/features/mods/components/InstalledContentTab.tsx
  • src/features/mods/components/ModReviewRow.tsx
  • src/features/skins/components/McstatApiKeyDialog.tsx
  • src/features/skins/pages/useSkinsBrowser.ts

Walkthrough

A 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.

Changes

Atualização do launcher

Layer / File(s) Summary
Documentação, release e qualidade
.github/..., README.md, AGENTS.md, docs/..., package.json, src-tauri/Cargo.toml
A documentação, as dependências, o script Knip, o Quality Gate e as notas da versão foram atualizados.
Memória sugerida e instalação de modpacks
src-tauri/app/application/use_cases/..., src-tauri/app/application/dto/...
O backend calcula memória sugerida e instala arquivos CurseForge e Modrinth com concorrência limitada, progresso, cancelamento e rollback.
Lançamento do Minecraft e estado da janela
src-tauri/app/application/use_cases/launch_instance.rs, src-tauri/app/infrastructure/minecraft/..., src-tauri/app/infrastructure/modloader/..., src-tauri/app/infrastructure/window_state.rs
O launcher configura o idioma, cria o perfil Forge/NeoForge, reporta progresso de bibliotecas e salva ou restaura o estado da janela.
Contratos e comandos backend
src-tauri/app/presentation/..., src-tauri/src/lib.rs, src-tauri/src/main.rs
O caso de uso de memória foi conectado ao estado da aplicação e ao comando Tauri get_suggested_memory.
Memória e controles da interface
src/features/instances/..., src/components/...
A interface consulta e aplica a memória sugerida, bloqueia ações duplicadas e adiciona tooltips, rótulos acessíveis e ajustes visuais.
Validação da chave MCStat
src/features/skins/components/..., src/features/skins/pages/...
O fluxo valida a chave por requisição real, exibe chaves inválidas e diferencia respostas 401 de outros erros.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed O título resume mudanças centrais da versão 0.5.2, incluindo persistência da janela, downloads paralelos e correções.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/v0.5.2

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Adicione nomes acessíveis aos dois botões.

tooltipProps registra apenas eventos de mouse. O tooltip não substitui aria-label para usuários de teclado e leitores de tela.

  • src/features/mods/components/InstalledContentTab.tsx#L155-L159: adicione aria-label="Excluir" ao botão.
  • src/features/mods/components/ModReviewRow.tsx#L51-L56: adicione aria-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 win

Adicione aria-label aos botões que contêm somente ícones.

tooltipProps registra apenas eventos de mouse. Ele não fornece um nome acessível para leitores de tela. Adicione aria-label aos botões Check, X e Pencil, 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 win

O tooltip pode permanecer visível após o clique.

O onClick nas linhas 159-163 define setShowScrollBtn(false). O botão é desmontado imediatamente. onMouseLeave não dispara em um elemento desmontado, então o tooltip global permanece na tela até o próximo show ou hide. Oculte o tooltip dentro do onClick.

🔧 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

📥 Commits

Reviewing files that changed from the base of the PR and between 2fe87f1 and 5405bd0.

⛔ Files ignored due to path filters (6)
  • docs/screenshots/demo.gif is excluded by !**/*.gif
  • docs/screenshots/editor.png is excluded by !**/*.png
  • docs/screenshots/home.png is excluded by !**/*.png
  • docs/screenshots/skins.png is excluded by !**/*.png
  • package-lock.json is excluded by !**/package-lock.json
  • src-tauri/Cargo.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (135)
  • .github/releases/v0.5.2.md
  • .github/workflows/quality-gate.yml
  • AGENTS.md
  • README.md
  • docs/01-visao-geral.md
  • docs/02-arquitetura.md
  • docs/04-modulos-e-dominios.md
  • docs/05-padroes-e-boas-praticas.md
  • docs/06-ipc-e-comunicacao.md
  • docs/08-infraestrutura.md
  • docs/11-dependencias-e-libs.md
  • docs/12-armazenamento.md
  • knip.json
  • package.json
  • src-tauri/Cargo.toml
  • src-tauri/app/application/dto/instance_dto.rs
  • src-tauri/app/application/dto/mod.rs
  • src-tauri/app/application/dto/mod_dto.rs
  • src-tauri/app/application/dto/skin_dto.rs
  • src-tauri/app/application/use_cases/astropack_service/astropack_import.rs
  • src-tauri/app/application/use_cases/astropack_service/content.rs
  • src-tauri/app/application/use_cases/delete_instance.rs
  • src-tauri/app/application/use_cases/duplicate_instance.rs
  • src-tauri/app/application/use_cases/instance_workspace/config_files.rs
  • src-tauri/app/application/use_cases/instance_workspace/notes.rs
  • src-tauri/app/application/use_cases/instance_workspace/shortcuts.rs
  • src-tauri/app/application/use_cases/launch_instance.rs
  • src-tauri/app/application/use_cases/memory_suggestion.rs
  • src-tauri/app/application/use_cases/mod.rs
  • src-tauri/app/application/use_cases/mod_manager.rs
  • src-tauri/app/application/use_cases/modpack_installer.rs
  • src-tauri/app/application/use_cases/modpack_installer/curseforge_install.rs
  • src-tauri/app/application/use_cases/modpack_installer/modrinth_install.rs
  • src-tauri/app/application/use_cases/playtime_service.rs
  • src-tauri/app/application/use_cases/skin_browser.rs
  • src-tauri/app/bootstrap/setup.rs
  • src-tauri/app/domain/entities/installed_mod.rs
  • src-tauri/app/domain/repositories/playtime_repository.rs
  • src-tauri/app/infrastructure/cli.rs
  • src-tauri/app/infrastructure/curseforge/client.rs
  • src-tauri/app/infrastructure/discord/rpc.rs
  • src-tauri/app/infrastructure/downloader/progress.rs
  • src-tauri/app/infrastructure/filesystem/safe_path.rs
  • src-tauri/app/infrastructure/filesystem/shortcut.rs
  • src-tauri/app/infrastructure/filesystem/shortcut/icon.rs
  • src-tauri/app/infrastructure/filesystem/shortcut/powershell.rs
  • src-tauri/app/infrastructure/minecraft/language.rs
  • src-tauri/app/infrastructure/minecraft/mod.rs
  • src-tauri/app/infrastructure/minecraft/servers_dat/write.rs
  • src-tauri/app/infrastructure/mod.rs
  • src-tauri/app/infrastructure/modloader/forge_like.rs
  • src-tauri/app/infrastructure/modloader/forge_like/command.rs
  • src-tauri/app/infrastructure/modloader/forge_like/install.rs
  • src-tauri/app/infrastructure/modloader/liteloader.rs
  • src-tauri/app/infrastructure/modloader/profile.rs
  • src-tauri/app/infrastructure/modrinth/client.rs
  • src-tauri/app/infrastructure/modrinth/client/dto.rs
  • src-tauri/app/infrastructure/modrinth/mrpack.rs
  • src-tauri/app/infrastructure/playermc/client.rs
  • src-tauri/app/infrastructure/process/launcher.rs
  • src-tauri/app/infrastructure/process/manager.rs
  • src-tauri/app/infrastructure/window_state.rs
  • src-tauri/app/presentation/commands/astropack_commands.rs
  • src-tauri/app/presentation/commands/discord_commands.rs
  • src-tauri/app/presentation/commands/instance_workspace_commands/shortcut_commands.rs
  • src-tauri/app/presentation/commands/minecraft_commands.rs
  • src-tauri/app/presentation/commands/mod_commands.rs
  • src-tauri/app/presentation/commands/splash_commands.rs
  • src-tauri/app/presentation/state/app_state.rs
  • src-tauri/src/lib.rs
  • src-tauri/src/main.rs
  • src-tauri/tauri.conf.json
  • src/App.tsx
  • src/components/common/CodeEditor.tsx
  • src/components/common/CursorTooltip.tsx
  • src/components/common/MarkdownBody.tsx
  • src/components/common/NumberStepperInput.tsx
  • src/components/common/PageHeader.tsx
  • src/components/common/SidebarNav.tsx
  • src/components/layout/ChangelogDialog.tsx
  • src/components/layout/TopBar.tsx
  • src/components/ui/scroll-area.tsx
  • src/features/accounts/components/AccountRow.tsx
  • src/features/instances/components/ConfirmDeleteFolderDialog.tsx
  • src/features/instances/components/IconPickerButton.tsx
  • src/features/instances/components/IconUploadTab.tsx
  • src/features/instances/components/InstanceCard.tsx
  • src/features/instances/components/InstanceSidebar.tsx
  • src/features/instances/components/InstancesBackground.tsx
  • src/features/instances/components/create-instance/ModpackBrowserPanel.tsx
  • src/features/instances/components/create-instance/ModpackVersionPicker.tsx
  • src/features/instances/components/create-instance/SourcePlaceholder.tsx
  • src/features/instances/components/edit-instance/ConfigFilesTab.tsx
  • src/features/instances/components/edit-instance/LogTab.tsx
  • src/features/instances/components/edit-instance/MemorySettingsSection.tsx
  • src/features/instances/components/edit-instance/NotesTab.tsx
  • src/features/instances/components/edit-instance/OptionsFileEmptyState.tsx
  • src/features/instances/components/edit-instance/ResizableImageExtension.tsx
  • src/features/instances/components/edit-instance/ScreenshotViewerDialog.tsx
  • src/features/instances/components/edit-instance/ScreenshotZoomControls.tsx
  • src/features/instances/components/edit-instance/ServersTab.tsx
  • src/features/instances/components/edit-instance/SettingsTab.tsx
  • src/features/instances/components/edit-instance/WorldsTab.tsx
  • src/features/instances/hooks/useInstancesPage.ts
  • src/features/instances/lib/instance-actions.ts
  • src/features/instances/pages/InstancesPage.tsx
  • src/features/mods/components/InstalledContentTab.tsx
  • src/features/mods/components/ModBrowserDialog.tsx
  • src/features/mods/components/ModReviewRow.tsx
  • src/features/mods/components/useModBrowser.ts
  • src/features/mods/components/useReviewEntries.ts
  • src/features/mods/services/mod.api.ts
  • src/features/skins/components/McstatApiKeyDialog.tsx
  • src/features/skins/components/SkinCard.tsx
  • src/features/skins/components/SkinDetailDialog.tsx
  • src/features/skins/components/SkinViewer3D.tsx
  • src/features/skins/components/useSkinDetail.ts
  • src/features/skins/lib/thumbnailQueue.ts
  • src/features/skins/lib/thumbnailRenderer.ts
  • src/features/skins/pages/SkinsPage.tsx
  • src/features/skins/pages/useSkinsBrowser.ts
  • src/hooks/useBlockBrowserNavigation.ts
  • src/hooks/useBlockNativeContextMenu.ts
  • src/hooks/useDiscordPresence.ts
  • src/lib/icon-src.ts
  • src/lib/keybind-labels.ts
  • src/lib/keybind-utils.ts
  • src/lib/minecraft-option-metadata.ts
  • src/lib/tooltip.ts
  • src/stores/import-astropack.store.ts
  • src/stores/launch.store.ts
  • src/stores/tooltip.store.ts
  • src/types/instance.ts
  • src/types/mods.ts
  • src/types/skins.ts
💤 Files with no reviewable changes (1)
  • knip.json

Comment thread docs/04-modulos-e-dominios.md Outdated
Comment on lines +7 to +17
| 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` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 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

Comment thread docs/08-infraestrutura.md Outdated
Comment thread docs/08-infraestrutura.md

- **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`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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 || true

Repository: 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.md

Repository: 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.rs

Repository: 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.

Comment on lines +9 to +37
| 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).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.json

Repository: 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 || true

Repository: 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.

Comment on lines +7 to 10
invalidKey?: boolean
onOpenChange: (open: boolean) => void
onSaved: (key: string) => void
onSubmit: (key: string) => Promise<void>
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 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/skins

Repository: 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.tsx

Repository: 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.

Comment thread src/features/skins/components/McstatApiKeyDialog.tsx Outdated
Comment on lines +115 to +117
invalidKey={mcstatKeyInvalid}
onOpenChange={setMcstatKeyDialogOpen}
onSaved={(key) => {
setMcstatApiKey(key)
setSource('mcstat')
}}
onSubmit={submitMcstatKey}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ 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.

Comment thread src/features/skins/pages/useSkinsBrowser.ts
Comment thread src/features/skins/pages/useSkinsBrowser.ts Outdated
@kauafpssx kauafpssx self-assigned this Aug 7, 2026
- 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant