docs: refresh docs and screenshots, drop em dashes, add scripts/screenshots.sh
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No files matched your search
@@ -4,6 +4,11 @@
|
||||
|
||||
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow SemVer.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- Documentation brought up to date (ROADMAP version table, platform matrix, version stamps) and rewritten without em dashes. The interface screenshots were retaken from the current build, and `scripts/screenshots.sh` now regenerates them.
|
||||
|
||||
## [1.5.0] - 2026-11-03
|
||||
|
||||
### Added
|
||||
@@ -23,7 +28,7 @@ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versio
|
||||
## [1.3.5] - 2026-10-31
|
||||
|
||||
### Added
|
||||
- **One-click desktop update.** The "Update now" button actually downloads, verifies (SHA-256) and installs the new version now, instead of only linking to the Releases page. Works for all three desktop packages: AppImage (atomic self-replace), `.deb` (`dpkg -i`, no new password prompt — the app is already running as root/administrator by the time you click it), and the Windows installer (silent `/S` install). On Linux, the app restarts itself automatically; on Windows, the installer runs silently but the app does not reopen on its own yet — start it again once the install finishes.
|
||||
- **One-click desktop update.** The "Update now" button actually downloads, verifies (SHA-256) and installs the new version now, instead of only linking to the Releases page. Works for all three desktop packages: AppImage (atomic self-replace), `.deb` (`dpkg -i`, no new password prompt, the app is already running as root/administrator by the time you click it), and the Windows installer (silent `/S` install). On Linux, the app restarts itself automatically; on Windows, the installer runs silently but the app does not reopen on its own yet, start it again once the install finishes.
|
||||
|
||||
### Changed
|
||||
- **The repository moved to the Ciberfauna organization** (`ciberfauna/guara`, was `lucasrguerra/guara`). **Important notice for existing installations:** versions up to 1.3.4 have the old location baked into their update check; they will not find this release automatically. Download 1.3.5 once manually from the new Releases page, and future update checks will work through the new location.
|
||||
@@ -31,7 +36,7 @@ Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versio
|
||||
## [1.3.4] - 2026-10-31
|
||||
|
||||
### Fixed
|
||||
- **Desktop app: only one window on startup.** The main window used to be visible from launch, so the unprivileged instance's normal window would show, flash while the system asked for the administrator password, and only then get replaced by the elevated relaunch's window a moment later. The window now stays hidden until elevation is resolved — either already elevated, elevation failed (the window then shows the warning), or this is the already-elevated relaunched instance — so only one window ever appears, matching Sabiá.
|
||||
- **Desktop app: only one window on startup.** The main window used to be visible from launch, so the unprivileged instance's normal window would show, flash while the system asked for the administrator password, and only then get replaced by the elevated relaunch's window a moment later. The window now stays hidden until elevation is resolved (either already elevated, elevation failed (the window then shows the warning), or this is the already-elevated relaunched instance) so only one window ever appears, matching Sabiá.
|
||||
|
||||
## [1.3.3] - 2026-10-30
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
Formato baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/); versões seguem SemVer.
|
||||
|
||||
## [Não lançado]
|
||||
|
||||
### Alterado
|
||||
- Documentação atualizada (tabela de versões do ROADMAP, matriz de plataformas, versões citadas) e reescrita sem travessões. As capturas de tela da interface foram refeitas a partir da versão atual, e o `scripts/screenshots.sh` agora as regera.
|
||||
|
||||
## [1.5.0] - 2026-11-03
|
||||
|
||||
### Adicionado
|
||||
@@ -23,7 +28,7 @@ Formato baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/);
|
||||
## [1.3.5] - 2026-10-31
|
||||
|
||||
### Adicionado
|
||||
- **Atualização do app desktop em um clique.** O botão "Atualizar agora" agora baixa, confere (SHA-256) e instala a versão nova de verdade, em vez de só linkar pra página de Releases. Funciona nos três pacotes do desktop: AppImage (substituição atômica), `.deb` (`dpkg -i`, sem pedir senha de novo — o app já roda como root/administrador quando você clica), e o instalador do Windows (instalação silenciosa `/S`). No Linux o app reabre sozinho; no Windows o instalador roda silencioso mas o app ainda não reabre por conta própria — abra de novo depois que a instalação terminar.
|
||||
- **Atualização do app desktop em um clique.** O botão "Atualizar agora" agora baixa, confere (SHA-256) e instala a versão nova de verdade, em vez de só linkar pra página de Releases. Funciona nos três pacotes do desktop: AppImage (substituição atômica), `.deb` (`dpkg -i`, sem pedir senha de novo, o app já roda como root/administrador quando você clica), e o instalador do Windows (instalação silenciosa `/S`). No Linux o app reabre sozinho; no Windows o instalador roda silencioso mas o app ainda não reabre por conta própria, abra de novo depois que a instalação terminar.
|
||||
|
||||
### Alterado
|
||||
- **O repositório se mudou pra organização Ciberfauna** (`ciberfauna/guara`, era `lucasrguerra/guara`). **Aviso importante pra instalações existentes:** versões até a 1.3.4 têm o endereço antigo fixo na checagem de atualização e não vão encontrar esta versão sozinhas. Baixe a 1.3.5 manualmente uma vez na nova página de Releases, e as próximas verificações voltam a funcionar pelo novo endereço.
|
||||
@@ -31,7 +36,7 @@ Formato baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/);
|
||||
## [1.3.4] - 2026-10-31
|
||||
|
||||
### Corrigido
|
||||
- **App desktop: só uma janela na abertura.** A janela principal ficava visível desde o lançamento, então a instância sem privilégio mostrava a janela normal, piscava enquanto o sistema pedia a senha de administrador, e só depois era substituída pela janela da instância já elevada. Agora a janela fica escondida até a elevação ser resolvida — já elevada, falhou (a janela aí mostra o aviso), ou é a própria instância já relançada como administrador — então só uma janela aparece, igual ao Sabiá.
|
||||
- **App desktop: só uma janela na abertura.** A janela principal ficava visível desde o lançamento, então a instância sem privilégio mostrava a janela normal, piscava enquanto o sistema pedia a senha de administrador, e só depois era substituída pela janela da instância já elevada. Agora a janela fica escondida até a elevação ser resolvida (já elevada, falhou (a janela aí mostra o aviso), ou é a própria instância já relançada como administrador) então só uma janela aparece, igual ao Sabiá.
|
||||
|
||||
## [1.3.3] - 2026-10-30
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ Create the reader in `crates/guara-core/src/fs/`, register it in `fs/mod.rs` and
|
||||
|
||||
The main version is in English and every file has a Portuguese translation (`*.pt-BR.md`, `docs/pt-BR/`). No em dashes or en dashes. When you change a feature, update both versions (English and Portuguese) of [docs/support.md](docs/support.md), the [CHANGELOG](CHANGELOG.md) and, if applicable, the [ROADMAP](ROADMAP.md).
|
||||
|
||||
The screenshots in `docs/img` are generated: run `scripts/screenshots.sh` to retake them from the current build (synthetic photo image, real scan). Run it again whenever the interface or the version shown on screen changes.
|
||||
|
||||
## Commits
|
||||
|
||||
Commits must follow **Conventional Commits 1.0.0** in English (`feat:`, `fix:`, `chore:`, `ci:`, `docs:`, `refactor:`, `test:`, `perf:`, `build:`), e.g. `fix(ntfs): handle sparse data runs correctly`. One logical change per PR. Enforced automatically by `.githooks/commit-msg`.
|
||||
@@ -47,6 +47,8 @@ Crie o leitor em `crates/guara-core/src/fs/`, registre-o em `fs/mod.rs` e traga
|
||||
|
||||
A versão principal é em inglês e cada arquivo tem uma tradução em português (`*.pt-BR.md`, `docs/pt-BR/`). Sem travessões. Ao mudar um recurso, atualize as duas versões (inglês e português) de [docs/support.md](docs/support.md), do [CHANGELOG](CHANGELOG.md) e, se for o caso, do [ROADMAP](ROADMAP.md).
|
||||
|
||||
As capturas de tela em `docs/img` são geradas: rode `scripts/screenshots.sh` para refazê-las a partir da versão atual (imagem de fotos sintética, varredura de verdade). Rode de novo sempre que a interface ou a versão exibida na tela mudar.
|
||||
|
||||
## Commits
|
||||
|
||||
Os commits devem seguir **Conventional Commits 1.0.0** em inglês (`feat:`, `fix:`, `chore:`, `ci:`, `docs:`, `refactor:`, `test:`, `perf:`, `build:`), ex.: `fix(ntfs): handle sparse data runs correctly`. Uma mudança lógica por PR. Validado automaticamente por `.githooks/commit-msg`.
|
||||
@@ -38,14 +38,14 @@ Download the package for your system from **[Releases](../../releases)**:
|
||||
|
||||
| | CLI | Graphical app |
|
||||
|---|---|---|
|
||||
| Windows | — | `.msi` / `.exe` installer |
|
||||
| Windows | none | `.msi` / `.exe` installer |
|
||||
| Linux | `guara-*-linux-{x86_64,aarch64}.tar.gz` | `.AppImage` / `.deb` |
|
||||
|
||||
The CLI is Linux-only; the desktop app ships for Linux and Windows. Every CLI
|
||||
package has a `.sha256` next to it. To build from source: `cargo build
|
||||
--release -p guara-cli` (Rust 1.80+, Linux).
|
||||
|
||||
**Updates:** the desktop app checks Gitea on startup; when a new version exists, a notice offers the release link. The CLI updates the same way (`guara update`); it downloads the right binary for your platform, verifies the **SHA-256** and swaps the running executable — no manual download. The check is a single request to the releases API and sends nothing of yours.
|
||||
**Updates:** the desktop app checks Gitea on startup; when a new version exists, a notice offers the release link. The CLI updates the same way (`guara update`); it downloads the right binary for your platform, verifies the **SHA-256** and swaps the running executable, no manual download. The check is a single request to the releases API and sends nothing of yours.
|
||||
|
||||
> The binaries are **not signed yet**: Windows SmartScreen will warn you. Check the SHA-256.
|
||||
|
||||
@@ -95,7 +95,7 @@ A desktop app (Tauri) in the style of a file manager, designed for when Guará f
|
||||
- **Timeline:** creation, modification and access dates from NTFS, FAT and exFAT.
|
||||
- **Text search across the whole disk**, including free space, in UTF-8 and UTF-16.
|
||||
- **CSV** (opens in Excel) and a printable **HTML report** with case, examiner, source, partitions, summary and hashes.
|
||||
- **Automatic sessions** and reconnection: Guará recognizes the same disk coming back under another name.
|
||||
- **Automatic sessions** and reconnection: Guará recognizes the same disk coming back under another name. Saved sessions can be deleted one by one or by age.
|
||||
- **Duplicate detection** by content signature.
|
||||
|
||||
> **Warning:** Guará has **not been externally validated** yet (for example, in the NIST CFTT tests) and has no trusted timestamp (RFC 3161) on its signatures. It is well suited to recovery and triage; for use in court, check the results by other means. The path to get there is in the [ROADMAP](ROADMAP.md).
|
||||
@@ -120,7 +120,7 @@ Summary of the [ROADMAP](ROADMAP.md):
|
||||
|---|---|
|
||||
| **Done** | Metadata from 8 file systems, BitLocker, LUKS, FileVault 2, RAID, LVM, E01, Ex01, AFF4, fragmented JPEG, MP4 without an index, SQLite reader, SMART, QCOW2/VMDK/VHD/VHDX/DMG, hash-chained audit trail, PDF report, Ed25519 signatures, APFS free map |
|
||||
| **Next** | Trusted timestamps (RFC 3161), more tests on Windows |
|
||||
| **Not planned** | A macOS build — see [Known limits](#known-limits) |
|
||||
| **Not planned** | A macOS build, see [Known limits](#known-limits) |
|
||||
| **Later** | NSRL and hash lists, content search, unified timeline, browser interpretation, Windows registry and messaging apps, dictionary and brute-force attacks on encrypted volumes |
|
||||
| **No reference image** | ReFS and Storage Spaces: they only land with validation |
|
||||
| **Long term** | iOS and Android backups (iTunes, ADB), OCR, NIST CFTT validation, physical phone access through bootloader/chip exploits |
|
||||
|
||||
@@ -38,14 +38,14 @@ Baixe o pacote do seu sistema em **[Releases](../../releases)**:
|
||||
|
||||
| | CLI | App gráfico |
|
||||
|---|---|---|
|
||||
| Windows | — | instalador `.msi` / `.exe` |
|
||||
| Windows | nenhum | instalador `.msi` / `.exe` |
|
||||
| Linux | `guara-*-linux-{x86_64,aarch64}.tar.gz` | `.AppImage` / `.deb` |
|
||||
|
||||
O CLI é só para Linux; o app desktop sai para Linux e Windows. Cada pacote do
|
||||
CLI tem um `.sha256` ao lado. Compilar do código: `cargo build --release -p
|
||||
guara-cli` (Rust 1.80+, Linux).
|
||||
|
||||
**Atualizações:** o app desktop consulta o Gitea ao abrir; havendo versão nova, um aviso oferece o link da release. O CLI atualiza do mesmo jeito (`guara update`); ele baixa o binário certo para a plataforma, confere o **SHA-256** e troca o executável em uso — você não precisa baixar nada na mão. A consulta é uma única requisição à API de releases e nada seu é enviado.
|
||||
**Atualizações:** o app desktop consulta o Gitea ao abrir; havendo versão nova, um aviso oferece o link da release. O CLI atualiza do mesmo jeito (`guara update`); ele baixa o binário certo para a plataforma, confere o **SHA-256** e troca o executável em uso, você não precisa baixar nada na mão. A consulta é uma única requisição à API de releases e nada seu é enviado.
|
||||
|
||||
> Os binários ainda **não são assinados**: o Windows SmartScreen vai avisar. Confira o SHA-256.
|
||||
|
||||
@@ -95,7 +95,7 @@ App desktop (Tauri) no estilo de um gerenciador de arquivos, pensado para quando
|
||||
- **Linha do tempo:** datas de criação, modificação e acesso do NTFS, FAT e exFAT.
|
||||
- **Busca de texto no disco inteiro**, inclusive espaço livre, em UTF-8 e UTF-16.
|
||||
- **CSV** (abre no Excel) e **relatório HTML** imprimível com caso, examinador, origem, partições, resumo e hashes.
|
||||
- **Sessões automáticas** e reconexão: o Guará reconhece o mesmo disco que volta com outro nome.
|
||||
- **Sessões automáticas** e reconexão: o Guará reconhece o mesmo disco que volta com outro nome. As sessões salvas podem ser apagadas uma a uma ou por idade.
|
||||
- **Detecção de duplicadas** por assinatura de conteúdo.
|
||||
|
||||
> **Atenção:** o Guará ainda **não foi validado externamente** (por exemplo, nos testes do NIST CFTT) e suas assinaturas não têm carimbo de tempo de terceiros (RFC 3161). Serve bem para recuperação e triagem; para uso em juízo, confira os resultados por outro meio. O caminho para isso está no [ROADMAP](ROADMAP.pt-BR.md).
|
||||
@@ -120,7 +120,7 @@ Resumo do [ROADMAP](ROADMAP.pt-BR.md):
|
||||
|---|---|
|
||||
| **Feito** | Metadados de 8 sistemas de arquivos, BitLocker, LUKS, FileVault 2, RAID, LVM, E01, Ex01, AFF4, JPEG fragmentado, MP4 sem índice, leitor de SQLite, SMART, QCOW2/VMDK/VHD/VHDX/DMG, trilha de auditoria encadeada por hash, relatório em PDF, assinaturas Ed25519, mapa livre do APFS |
|
||||
| **Próximo** | Carimbo de tempo de terceiros (RFC 3161), mais testes em Windows |
|
||||
| **Fora de plano** | Um build para macOS — veja [Limites conhecidos](#limites-conhecidos) |
|
||||
| **Fora de plano** | Um build para macOS, veja [Limites conhecidos](#limites-conhecidos) |
|
||||
| **Depois** | NSRL e listas de hashes, busca em conteúdo, linha do tempo unificada, interpretação de navegadores, registro do Windows e apps de mensagem, ataque de dicionário e força bruta a volumes cifrados |
|
||||
| **Sem imagem de referência** | ReFS e Storage Spaces: só entram com validação |
|
||||
| **Longo prazo** | Backups de iOS e Android (iTunes, ADB), OCR, validação NIST CFTT, acesso físico a celulares por exploit de bootloader/chip |
|
||||
|
||||
@@ -8,7 +8,7 @@ Legend: ✅ done · 🟡 partial · 🔜 planned · 🔭 long-term idea · ⛔ o
|
||||
|
||||
> Items marked done for macOS reflect what the GitHub CI used to build and test,
|
||||
> before the move to Gitea. The Gitea CI has one Linux runner; it builds and
|
||||
> tests Linux and Windows. macOS is not built or tested any more — see the
|
||||
> tests Linux and Windows. macOS is not built or tested any more, see the
|
||||
> README's [Known limits](README.md#known-limits).
|
||||
|
||||
## Principles that do not change
|
||||
@@ -34,10 +34,16 @@ Legend: ✅ done · 🟡 partial · 🔜 planned · 🔭 long-term idea · ⛔ o
|
||||
| 1.2.0 | 2026-10-22 | QCOW2, VMDK, VHD, VHDX and DMG virtual disks, hash-chained audit trail, PDF report, APFS free-space map |
|
||||
| 1.3.0 | 2026-10-23 | Update from inside the app, Ed25519 signatures, differencing QCOW2/VMDK and LZFSE DMG, reference images tested on Linux, macOS and Windows, XFS real-deletion test |
|
||||
| 1.3.1 | 2026-10-23 | New official logo |
|
||||
| 1.3.2 | 2026-10-30 | Updates come from Gitea |
|
||||
| 1.3.3 | 2026-10-30 | New update mechanism (same model as Sabiá), `guara update` for the CLI |
|
||||
| 1.3.4 | 2026-10-31 | Desktop app opens a single window at startup |
|
||||
| 1.3.5 | 2026-10-31 | One-click desktop update, repository moved to the Ciberfauna organization |
|
||||
| 1.4.0 | 2026-11-03 | Browse by folder, recover whole folders or parts of them |
|
||||
| 1.5.0 | 2026-11-03 | Update progress bar and no more freezing, instant Pause/Stop, delete saved sessions manually or by age |
|
||||
|
||||
Details of each version in the [CHANGELOG](CHANGELOG.md).
|
||||
|
||||
## Current status (1.3.1) against what is expected from a forensic suite
|
||||
## Current status (1.5.0) against what is expected from a forensic suite
|
||||
|
||||
### 1. File systems with metadata
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Legenda: ✅ feito · 🟡 parcial · 🔜 planejado · 🔭 ideia a longo prazo
|
||||
|
||||
> Itens marcados como feitos para macOS refletem o que o CI do GitHub compilava e
|
||||
> testava, antes da mudança para o Gitea. O CI do Gitea tem um único runner Linux;
|
||||
> ele compila e testa Linux e Windows. O macOS deixou de ser compilado e testado —
|
||||
> ele compila e testa Linux e Windows. O macOS deixou de ser compilado e testado,
|
||||
> veja os [Limites conhecidos](README.pt-BR.md#limites-conhecidos) do README.
|
||||
|
||||
## Princípios que não mudam
|
||||
@@ -34,10 +34,16 @@ Legenda: ✅ feito · 🟡 parcial · 🔜 planejado · 🔭 ideia a longo prazo
|
||||
| 1.2.0 | 2026-10-22 | Discos virtuais QCOW2, VMDK, VHD, VHDX e DMG, trilha de auditoria encadeada por hash, relatório em PDF, mapa de espaço livre do APFS |
|
||||
| 1.3.0 | 2026-10-23 | Atualização pelo próprio app, assinaturas Ed25519, QCOW2/VMDK diferenciais e DMG com LZFSE, imagens de referência testadas em Linux, macOS e Windows, teste de exclusão real do XFS |
|
||||
| 1.3.1 | 2026-10-23 | Nova logo oficial |
|
||||
| 1.3.2 | 2026-10-30 | As atualizações passam a vir do Gitea |
|
||||
| 1.3.3 | 2026-10-30 | Novo mecanismo de atualização (mesmo modelo do Sabiá), `guara update` no CLI |
|
||||
| 1.3.4 | 2026-10-31 | O app desktop abre uma única janela ao iniciar |
|
||||
| 1.3.5 | 2026-10-31 | Atualização do app desktop em um clique, repositório movido para a organização Ciberfauna |
|
||||
| 1.4.0 | 2026-11-03 | Navegação por pastas, recuperação de pastas inteiras ou de partes delas |
|
||||
| 1.5.0 | 2026-11-03 | Barra de progresso da atualização sem travar o app, Pausar/Parar imediatos, apagar sessões salvas à mão ou por idade |
|
||||
|
||||
Detalhes de cada versão no [CHANGELOG](CHANGELOG.pt-BR.md).
|
||||
|
||||
## Situação atual (1.3.1) contra o que se espera de uma suíte forense
|
||||
## Situação atual (1.5.0) contra o que se espera de uma suíte forense
|
||||
|
||||
### 1. Sistemas de arquivos com metadados
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ guara report s.json report.html --case 2026-001 --examiner "Name" --hash-source
|
||||
|
||||
Includes case identification, source, partitions, summary, hashes, the audit trail status and the list of files. `--hash-source` adds the hash of the whole source. The format follows the extension: `report.pdf` writes an A4 PDF (standard fonts, nothing external), anything else writes HTML.
|
||||
|
||||
## `update` — updating
|
||||
## `update`: updating
|
||||
|
||||
```bash
|
||||
guara update # check for a new version
|
||||
|
||||
|
Before Width: | Height: | Size: 693 KiB After Width: | Height: | Size: 614 KiB |
|
Before Width: | Height: | Size: 700 KiB After Width: | Height: | Size: 622 KiB |
|
Before Width: | Height: | Size: 698 KiB After Width: | Height: | Size: 618 KiB |
|
Before Width: | Height: | Size: 706 KiB After Width: | Height: | Size: 626 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 66 KiB |
@@ -51,4 +51,4 @@ Error messages that come from the core, and the terminal output, are still in Po
|
||||
|
||||
## About these screenshots
|
||||
|
||||
They show the real interface, not a mock-up, running on a synthetic test image: 72 generated JPEGs with fake EXIF (cameras, dates, GPS) that were deleted from a FAT32 image by `scripts/make-photo-fixture.py` and found by a normal `guara scan`. No real data appears. The device name in the sidebar was replaced with a generic one.
|
||||
They show the real interface, not a mock-up, running on a synthetic test image: 72 generated JPEGs with fake EXIF (cameras, dates, GPS) that were deleted from a FAT32 image by `scripts/make-photo-fixture.py` and found by a normal `guara scan`. No real data appears. The device name in the sidebar was replaced with a generic one. They are regenerated by `scripts/screenshots.sh` (see [CONTRIBUTING.md](../CONTRIBUTING.md)).
|
||||
@@ -150,7 +150,7 @@ guara report s.json relatorio.html --case 2026-001 --examiner "Nome" --hash-sour
|
||||
|
||||
Traz identificação do caso, origem, partições, resumo, hashes, a situação da trilha de auditoria e a lista dos arquivos. `--hash-source` inclui o hash da origem inteira. O formato segue a extensão: `relatorio.pdf` gera um PDF A4 (fontes padrão, nada externo); qualquer outra gera HTML.
|
||||
|
||||
## `update` — atualizações
|
||||
## `update`: atualizações
|
||||
|
||||
```bash
|
||||
guara update # verifica se há versão nova
|
||||
|
||||
@@ -51,4 +51,4 @@ As mensagens de erro que vêm do núcleo e a saída do terminal continuam em por
|
||||
|
||||
## Sobre estas telas
|
||||
|
||||
Mostram a interface de verdade, não uma maquete, rodando sobre uma imagem de teste sintética: 72 JPEGs gerados com EXIF falso (câmeras, datas, GPS), apagados de uma imagem FAT32 por `scripts/make-photo-fixture.py` e encontrados por um `guara scan` normal. Nenhum dado real aparece. O nome do dispositivo na barra lateral foi trocado por um genérico.
|
||||
Mostram a interface de verdade, não uma maquete, rodando sobre uma imagem de teste sintética: 72 JPEGs gerados com EXIF falso (câmeras, datas, GPS), apagados de uma imagem FAT32 por `scripts/make-photo-fixture.py` e encontrados por um `guara scan` normal. Nenhum dado real aparece. O nome do dispositivo na barra lateral foi trocado por um genérico. Elas são regeradas por `scripts/screenshots.sh` (veja [CONTRIBUTING.pt-BR.md](../../CONTRIBUTING.pt-BR.md)).
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](../support.md) · **Português**
|
||||
|
||||
Matriz do que existe hoje (versão 1.3.2). Para o que vem a seguir, veja o [ROADMAP](../../ROADMAP.pt-BR.md).
|
||||
Matriz do que existe hoje (versão 1.5.0). Para o que vem a seguir, veja o [ROADMAP](../../ROADMAP.pt-BR.md).
|
||||
|
||||
## Tabelas de partição
|
||||
|
||||
@@ -99,8 +99,8 @@ A pré-visualização é lida direto do disco, sem gravar nada: imagem, vídeo,
|
||||
| | CLI | Interface | Testes com imagens reais |
|
||||
|---|---|---|---|
|
||||
| Linux | ✅ | ✅ AppImage e deb | ✅ |
|
||||
| Windows | ✅ | ✅ msi e exe | só compilação e testes sintéticos |
|
||||
| macOS | ✅ | ✅ dmg | só compilação e testes sintéticos |
|
||||
| Windows | ❌ sem binário na release | ✅ instalador exe | só compilação e testes sintéticos |
|
||||
| macOS | ❌ não compilado nem testado | ❌ sem build | ❌ |
|
||||
|
||||
## O que o Guará não faz
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](support.md) · [Português](pt-BR/suporte.md)
|
||||
|
||||
Matrix of what exists today (version 1.3.2). For what comes next, see the [ROADMAP](../ROADMAP.md).
|
||||
Matrix of what exists today (version 1.5.0). For what comes next, see the [ROADMAP](../ROADMAP.md).
|
||||
|
||||
## Partition tables
|
||||
|
||||
@@ -99,8 +99,8 @@ The preview is read straight from the disk, without writing anything: image, vid
|
||||
| | CLI | Interface | Tests with real images |
|
||||
|---|---|---|---|
|
||||
| Linux | ✅ | ✅ AppImage and deb | ✅ |
|
||||
| Windows | ✅ | ✅ msi and exe | build and synthetic tests only |
|
||||
| macOS | ✅ | ✅ dmg | build and synthetic tests only |
|
||||
| Windows | ❌ no release binary | ✅ exe installer | build and synthetic tests only |
|
||||
| macOS | ❌ not built or tested | ❌ no build | ❌ |
|
||||
|
||||
## What Guará does not do
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regera as capturas de tela de docs/img a partir da interface real do Guará.
|
||||
#
|
||||
# Dados: uma imagem FAT32 sintética com 72 fotos JPEG apagadas (EXIF falso de câmera, data e
|
||||
# GPS), gerada por scripts/make-photo-fixture.py e encontrada por uma varredura de verdade. A
|
||||
# lista de dispositivos do computador é substituída por um nome genérico. Nenhum dado real.
|
||||
#
|
||||
# scripts/screenshots.sh # grava em docs/img
|
||||
# OUT=/tmp/img scripts/screenshots.sh # grava em outro diretório
|
||||
#
|
||||
# Gera explorer-{dark,light}-{pt,en}, folders-light-{pt,en} e settings-language-{pt,en}.
|
||||
# Variáveis: OUT, GUARA_BIN (padrão target/release/guara; sempre recompilado se não for dado,
|
||||
# porque a interface vai embutida no binário), CHROME, PUPPETEER_CORE (padrões: Chrome do cache
|
||||
# do puppeteer e puppeteer-core em ~/.claude/tools/node_modules).
|
||||
# Requer: python3, ImageMagick (convert), mkfs.vfat e mtools (mmd, mcopy, mdel), node e Chrome.
|
||||
# Usa /tmp/test-photos.img (a imagem aparece com esse caminho na barra lateral das capturas).
|
||||
set -euo pipefail
|
||||
|
||||
root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
out=${OUT:-$root/docs/img}
|
||||
image=/tmp/test-photos.img
|
||||
|
||||
if [ -z "${GUARA_BIN:-}" ]; then
|
||||
(cd "$root" && cargo build --release -p guara-cli)
|
||||
GUARA_BIN=$root/target/release/guara
|
||||
fi
|
||||
mkdir -p "$out"
|
||||
python3 "$root/scripts/make-photo-fixture.py" "$image" 72
|
||||
trap 'rm -f "$image"' EXIT
|
||||
|
||||
node "$root/scripts/screenshots/shots.mjs" "$GUARA_BIN" "$image" "$out"
|
||||
echo "capturas gravadas em $out"
|
||||
@@ -0,0 +1,129 @@
|
||||
// Captura a interface do Guará (explorer, vista de pastas e configurações) nos temas
|
||||
// claro/escuro e nos idiomas pt/en. Chamado por scripts/screenshots.sh:
|
||||
// node shots.mjs <binário guara> <imagem de teste> <dir-saída>
|
||||
import { execFileSync, spawn } from "node:child_process";
|
||||
import { homedir } from "node:os";
|
||||
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
const [bin, image, out] = process.argv.slice(2);
|
||||
const core = process.env.PUPPETEER_CORE || `${homedir()}/.claude/tools/node_modules/puppeteer-core/lib/esm/puppeteer/puppeteer-core.js`;
|
||||
const { default: puppeteer } = await import(core);
|
||||
const chrome = process.env.CHROME || execFileSync("bash", ["-c", `ls -1d "$HOME"/.cache/puppeteer/chrome/*/chrome-linux64/chrome | sort -V | tail -1`], { encoding: "utf8" }).trim();
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
// Dispositivo fictício: a lista real do computador não deve aparecer nas capturas.
|
||||
const FAKE_DEVICES = [{ path: "/dev/nvme0n1", name: "SSD interno", kind: "NVMe", size: 954 * 1024 ** 3, readable: false, mounted_at: [], removable: false }];
|
||||
const LABEL = "Pendrive 64 GB";
|
||||
|
||||
const variants = [
|
||||
{ theme: "dark", lang: "pt" }, { theme: "dark", lang: "en" },
|
||||
{ theme: "light", lang: "pt" }, { theme: "light", lang: "en" },
|
||||
];
|
||||
|
||||
// Sobe `guara ui` com config isolada (sessões e ajustes próprios) e devolve a URL com o token.
|
||||
async function startServer(theme, lang) {
|
||||
const cfg = mkdtempSync(join(tmpdir(), "guara-shots-"));
|
||||
mkdirSync(cfg, { recursive: true });
|
||||
writeFileSync(join(cfg, "settings.json"), JSON.stringify({ theme, lang, notify: true, maps: false, updates: false }));
|
||||
const child = spawn(bin, ["ui", "--no-open", "--port", "0"], { env: { ...process.env, GUARA_CONFIG_DIR: cfg }, stdio: ["ignore", "ignore", "pipe"] });
|
||||
const url = await new Promise((resolve, reject) => {
|
||||
let buf = "";
|
||||
child.stderr.on("data", (d) => { buf += d; const m = buf.match(/http:\/\/\S+/); if (m) resolve(m[0]); });
|
||||
child.on("exit", () => reject(new Error("guara ui saiu antes de subir")));
|
||||
setTimeout(() => reject(new Error("timeout subindo guara ui")), 20000);
|
||||
});
|
||||
return { url, stop: () => { child.kill(); rmSync(cfg, { recursive: true, force: true }); } };
|
||||
}
|
||||
|
||||
async function newPage(browser, url, w = 1600, h = 940) {
|
||||
const page = await browser.newPage();
|
||||
await page.setViewport({ width: w, height: h, deviceScaleFactor: 1 });
|
||||
await page.setRequestInterception(true);
|
||||
page.on("request", (req) => {
|
||||
if (req.url().includes("/rpc/devices")) {
|
||||
req.respond({ status: 200, contentType: "application/json", body: JSON.stringify(FAKE_DEVICES) });
|
||||
} else req.continue();
|
||||
});
|
||||
await page.goto(url, { waitUntil: "networkidle0" });
|
||||
await sleep(1200);
|
||||
return page;
|
||||
}
|
||||
|
||||
// Abre a imagem de teste, faz a varredura profunda e espera terminar.
|
||||
async function scanImage(page) {
|
||||
await page.click("#openImageBtn");
|
||||
await sleep(400);
|
||||
await page.type("#dlg input[name=v]", image);
|
||||
await page.click("#dlg button[value=ok]");
|
||||
await sleep(1200);
|
||||
await page.click("#goDeep");
|
||||
await page.waitForFunction(() => document.querySelector(".xp-tile, .xp-lrow"), { timeout: 120000 });
|
||||
await page.waitForFunction(() => !document.querySelector("#progressArea .progress-card"), { timeout: 120000 });
|
||||
await sleep(2500); // miniaturas e autosave da sessão
|
||||
}
|
||||
|
||||
const relabel = (page) => page.evaluate((t) => {
|
||||
const sub = document.querySelector("#scanSub"); if (sub) sub.innerHTML = `<span class="mono">${t}</span>`;
|
||||
}, LABEL);
|
||||
|
||||
const browser = await puppeteer.launch({ executablePath: chrome, args: ["--no-sandbox"] });
|
||||
try {
|
||||
for (const { theme, lang } of variants) {
|
||||
const srv = await startServer(theme, lang);
|
||||
try {
|
||||
// 1ª rodada: só para deixar uma sessão salva em "Recentes" (a 2ª rodada cria a outra).
|
||||
let page = await newPage(browser, srv.url);
|
||||
await scanImage(page);
|
||||
await page.close();
|
||||
|
||||
page = await newPage(browser, srv.url);
|
||||
await page.evaluate(() => { try { localStorage.setItem("guara-view", "grid"); } catch {} });
|
||||
await page.reload({ waitUntil: "networkidle0" });
|
||||
await sleep(1000);
|
||||
await scanImage(page);
|
||||
await relabel(page);
|
||||
|
||||
// Explorador em grade, com a primeira foto marcada.
|
||||
const chk = await page.$(".xp-tile .xp-chk");
|
||||
if (chk) await chk.click(); else await (await page.$(".xp-tile")).click();
|
||||
await sleep(800);
|
||||
await page.screenshot({ path: `${out}/explorer-${theme}-${lang}.png` });
|
||||
console.log("ok", `explorer-${theme}-${lang}`);
|
||||
|
||||
if (theme === "light") {
|
||||
// Vista de pastas: pasta DCIM marcada e selecionada.
|
||||
await page.click('button[data-view="folders"]');
|
||||
await sleep(1000);
|
||||
const dcim = await page.$('.xp-lrow.xp-dir[data-dir="0"]');
|
||||
await (await dcim.$(".xp-chk")).click();
|
||||
await sleep(400);
|
||||
await dcim.click({ offset: { x: 200, y: 20 } });
|
||||
await sleep(800);
|
||||
await relabel(page);
|
||||
await page.screenshot({ path: `${out}/folders-${theme}-${lang}.png` });
|
||||
console.log("ok", `folders-${theme}-${lang}`);
|
||||
await page.click('button[data-view="grid"]');
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
if (theme === "light") {
|
||||
// Diálogo de configurações, recortado com a moldura borrada ao redor.
|
||||
await page.click("#settingsBtn");
|
||||
await sleep(900);
|
||||
const box = await (await page.$("#dlg")).boundingBox();
|
||||
const pad = 24;
|
||||
await page.screenshot({
|
||||
path: `${out}/settings-language-${lang}.png`,
|
||||
clip: { x: Math.max(0, box.x - pad), y: Math.max(0, box.y - pad), width: box.width + 2 * pad, height: box.height + 2 * pad },
|
||||
});
|
||||
console.log("ok", `settings-language-${lang}`);
|
||||
}
|
||||
} finally {
|
||||
srv.stop();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||