Skip to content

feat(diagnostics): show the debug bundle in the file manager - #90

Merged
elementalvoid merged 2 commits into
elementalvoid:integration/kit-surfacefrom
jay23606:fix/87-reveal-archive-in-file-manager
Oct 31, 2026
Merged

elementalvoid merged 2 commits into
elementalvoid:integration/kit-surfacefrom
jay23606:fix/87-reveal-archive-in-file-manager

Conversation

@jay23606

Copy link
Copy Markdown
Contributor

Fixes #87

What

Adds a Show in folder control beside the debug bundle's Copy path. It opens the archive's folder in the file manager:

  • Windows: explorer /select,<archive>
  • macOS: open -R <archive>
  • Linux: xdg-open <folder> (no launcher selects a file there)

It reuses the platform dispatch in folder_panel.rs: reveal_command() picks the program and arguments, and spawn_reaped() starts the child and reaps it off-thread, the same as open_in_file_manager(). The control writes nothing to the clipboard and shows no confirmation, as the issue asks. Copy path is unchanged.

Base

Based on integration/kit-surface, as the issue asks, because the diagnostics surface was rewritten by #80 and #82. It will need a rebase if main moves before that stack merges.

Tests

  • New unit test reveal_selects_the_archive_or_opens_its_folder_per_platform: written first and red (reveal_command missing), then green. Each platform branch is checked by its own CI job.
  • cargo fmt --all -- --check: clean
  • cargo clippy -p immich-sync --all-targets -- -D warnings: clean
  • cargo test -p immich-sync: all passing (Windows)

Not covered by a headless test: the button click itself. A test would open a real file manager, so the click path is not exercised automatically.

🤖 Generated with Claude Code

Adds a "Show in folder" control beside the debug bundle's Copy path. It
opens the archive's folder in the file manager, selecting the archive on
Windows and macOS and opening the containing folder on Linux. It reuses
the existing platform dispatch in folder_panel.rs and writes nothing to
the clipboard. Copy path is unchanged.

Fixes #87

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
@elementalvoid

elementalvoid commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Thanks — this is close, and the shape is right: based on integration/kit-surface, no clipboard
write, no confirmation, Copy path untouched, and the row only exists in the Ready arm so "absent
until an archive exists" is structural. One detail shows real care: adding spawn_reaped and
leaving open_in_file_manager's signature alone matters, because dashboard.rs:88 uses it as a
FolderOpener closure — changing it would have rippled into the dashboard.

Review note: this review was done by an AI agent on the maintainer's behalf, so treat it as
the maintainer's review with one caveat — no file manager was actually launched on any platform
from this side. The reasoning below is from the code.

Three things before merge

1. The click is untestable for a reason the repo already solved. reveal_bundle calls
crate::folder_panel::reveal_in_file_manager directly, so the only way to exercise the click is to
launch a real file manager — hence "not covered by a headless test". But #43 hit exactly this and
fixed it with an injectable seam: pub type FolderOpener = Arc<dyn Fn(&str) -> std::io::Result<()>>
(folder_panel.rs:58), defaulting to the real implementation and swapped out in tests
(dashboard.rs:140). Mirroring that here — one field, one with_revealer constructor — turns the
click into an ordinary test.

2. It fails silently. On error the view only does tracing::warn!. #43's precedent is
self.problem = Some(format!("The folder could not be opened: {error}"))
(folder_panel.rs:623-626), rendered as the panel's error notice. A button that visibly does
nothing when it fails is worse than no button. This is a Notice (Severity::Error), not the
confirmation the issue rules out — a failure is a refusal, not feedback.

3. The view-level criteria aren't pinned. The unit test covers the platform table nicely, but
not: the control is absent when there is no archive, present and named when Ready, and keyboard
reachable. That is the normal shape in tests/diagnostics.rs, and it is cheap once the seam from
(1) exists.

Nice to have, not required

Windows path with spaces. You are building on Windows, and the debug bundle lands in the user
profile's Downloads, so C:\Users\Jane Doe\Downloads\… is a realistic path. explorer /select,<path>
should survive Rust's argument quoting, but that is the one thing I cannot check from Linux. If you
can try it once with a space in the path, that would close the last unknown here. Not a blocker if
you would rather not.

@jay23606

Copy link
Copy Markdown
Contributor Author

Show in folder now goes through an injectable opener (DiagnosticsView::with_revealer), so the click is exercised by a headless test instead of launching a real file manager. A refused launch now shows an error notice beside the control as well as logging it, and the new test checks the control's name, its keyboard reach, its absence before an archive exists, and that notice. I have not tried a Windows path with spaces in Explorer, so that case is still unchecked.

@elementalvoid
elementalvoid merged commit 1c53e30 into elementalvoid:integration/kit-surface Oct 31, 2026
5 checks passed
@elementalvoid

Copy link
Copy Markdown
Owner

Thanks @jay23606!

elementalvoid added a commit that referenced this pull request Oct 31, 2026
The shell stack moves to gpui-kit 0.8.1 and the hand-built surfaces become the
kit's: the surface switch, every notice, the three empty states, the settings
pages and rows, the folder filter select, the folder panel's dialog host, and
the diagnostics value rows. Copy actions confirm, and the debug bundle can be
shown in the file manager (#90).

Ten tickets, each built on its own branch and reviewed on two axes before
merge. Every review found defects a green suite could not see, and the ones
worth remembering are recorded in docs/agents/ui.md rather than only here:
an aria_label on a role-less div produces no accessibility node at all; no
live region means nothing is announced on any platform; the kit's dialog
swallows Enter before the focused control sees it; its sidebar is pointer-only.

Gate on this tree: cargo fmt --check clean, cargo clippy --workspace
--all-targets -D warnings clean, cargo test --workspace green, and the same
tree passed CI on integration/kit-surface at 43223e2.

Still manual, as each ticket records: no real screen reader on any platform,
and no macOS/Windows runtime — tray, menu bar, window show/hide, and the MSVC
job are unverified from the development host.
elementalvoid added a commit that referenced this pull request Oct 31, 2026
`gpui_kit::init` initialises the component and base layers and sets no asset
source, and `run_client` set none either, so every SVG the kit draws loaded
from nothing: the select's dropdown caret, a checked option row, and any
icon-only affordance in the components the #74-#90 stack adopted were all
blank.

`run_client` now builds its `Application` with
`with_assets(gpui_kit::assets::Assets)`, on the one application the window, the
tray and every capture run from, so the registration holds for every entry
point there is.

`Assets` is the 106-icon default component bundle (46,936 B of SVG), not
`AllAssets` (1,830 icons, 749,008 B). Every `IconName` a kit component can name
is one of the 106, and the app itself names only `Check`, so the larger bundle
would buy nothing. The debug binary grows 251,936 B (291,295,488 ->
291,547,424) for the payload and its embed table. The bundle carries icons
only, so nothing else is styled by the asset source.

The selected option row now draws the kit's `IconName::Check` beside its
semibold label; #79 left it weight-only because no icon could draw. The kit's
own row has that trailing slot, but `searchable_list/adapter.rs` in 0.8.1 only
sets `checked` on the slot when the delegate leaves `render_item` to the kit,
and this row is ours for the name and `aria_selected`, so the mark is drawn in
the row. No new test: the harness has no asset source, so a glyph is provable
only by capture, and the row's ids, name and selected state are unchanged.

Captures under Xvfb + lavapipe from one seed, same argument list for both
binaries, differing pixels between the binary at 35691b2 and this tree:

  surface                 theme  size     changed
  failed filter, closed   light  520x480  28 px, 10x6 at (192,165): the caret
  failed filter, closed   dark   520x480  28 px, same box
  failed filter, closed   light  900x650  28 px, same box
  failed filter, closed   dark   900x650  28 px, same box
  folder filter popup     light  520x480  55 px: caret + 10x7 at (178,205)
  folder filter popup     dark   520x480  55 px: same two boxes
  folder filter popup     light  900x650  55 px
  folder filter popup     dark   900x650  55 px

Every other pixel is unchanged, so the glyphs added no reflow: the caret sits
13 px inside the trigger's right border (trigger x 24..215, caret 192..202) and
12 px above its bottom edge, and the check ends 23 px before the row's right
edge, at 520x480 and at the default size. The app's dialogs gained nothing:
their close control is an app-drawn text control, and a dialog shot is
byte-identical before and after in both themes at 520x480.

Gate: cargo fmt --all -- --check clean, cargo clippy --workspace --all-targets
-- -D warnings clean, cargo test --workspace green (61 suites, 904 passed, 0
failed, 2 ignored).

Still manual: macOS and Windows rendering of the same glyphs, and no test
asserts an icon, because the headless harness runs without an asset source.
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.

2 participants