Skip to content

GUI-first exe with chromeless in-window report (increment 2) - #4

Merged
CameronCrow merged 1 commit into
mainfrom
hal/gui-first-dispatch
Jun 26, 2026
Merged

CameronCrow merged 1 commit into
mainfrom
hal/gui-first-dispatch

Conversation

@CameronCrow

Copy link
Copy Markdown
Owner

What

Makes the standalone exe GUI-first and opens the interactive report in a chromeless window — the behavior already documented by docs PR #3.

  • GUI-first dispatch. cli.main opens the Tkinter desktop GUI when launched with no arguments (double-click / Start menu), and runs the command-line scanner when given a path or any flag. --gui still forces the GUI explicitly.
  • Console handling. Stays a console-subsystem build so the CLI can print. gui._maybe_hide_console() hides the console via ctypes only when the process exclusively owns it (GetConsoleProcessList() == 1, i.e. a double-click), so a shared terminal is never hidden.
  • Chromeless in-window report. After a GUI scan, the HTML report opens automatically in an Edge (or Chrome) --app=file://... window via stdlib subprocess (find_app_browser / app_window_argv / open_report_window), falling back to webbrowser.open when neither is found. No new runtime dependency — the zero-dep / single-exe identity holds.
  • Packaging. storageanalyzer.spec lists tkinter in hiddenimports so the GUI is always bundled (native walker present or not).

Tests

  • tests/test_cli.py (new) — pins no-args → GUI, --gui → GUI, and path-arg → CLI dispatch without standing up Tk or running a real scan.
  • tests/test_gui.py — adds chromeless --app argv construction + report-window browser/fallback coverage.
  • Full suite green: 48 passed (miniconda 3.13).

Scope

Code + tests only. The README is handled separately on docs PR #3 (hal/docs-gui-first).

⚠️ Merge ordering

This PR and docs PR #3 must BOTH merge before the v* release tag is cut. PR #3 documents this behavior; this PR implements it. Tagging a release with only one of them landed would leave main's docs and code out of sync. (Do not merge or tag here — release is a separate task.)

🤖 Generated with Claude Code

…eport

The single exe now opens the desktop GUI when launched with no arguments and
runs the CLI when given a path or any flag (cli.main dispatches to gui.main on
empty argv). It stays a console-subsystem build so the CLI can still print;
gui._maybe_hide_console() hides the console via ctypes ONLY when the process
exclusively owns it (GetConsoleProcessList == 1, i.e. a double-click) so a
shared terminal is never hidden.

After a GUI scan completes, the interactive HTML report opens automatically in
a chromeless desktop window via Edge (or Chrome) `--app=file://...` launched
with stdlib subprocess (find_app_browser / app_window_argv / open_report_window),
falling back to webbrowser.open when neither browser is found -- preserving the
zero-runtime-dependency / single-exe identity.

storageanalyzer.spec lists tkinter in hiddenimports so the GUI is always bundled.

Tests: tests/test_cli.py pins the no-args/--gui/path dispatch; tests/test_gui.py
adds chromeless-argv + report-window fallback coverage. Full suite green (48).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CameronCrow
CameronCrow marked this pull request as ready for review June 26, 2026 20:01
@CameronCrow
CameronCrow merged commit 3bf6aa5 into main Jun 26, 2026
1 check passed
@CameronCrow
CameronCrow deleted the hal/gui-first-dispatch branch June 26, 2026 20:01
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