audit cleanup + DXGI probe for Windows-arm winget#38
Merged
Conversation
Pure formatting pass over the src/ tree to establish a rustfmt- clean baseline before adding `cargo fmt --check` as a CI gate in the next commit. No behaviour or logic changes — `cargo clippy --all-targets -- -D warnings` and `cargo test` both pass unchanged (63 tests). The drift accumulated organically over Phase 2 onwards; locking the baseline now keeps subsequent module splits (app_view, settings_view) on the rustfmt grid so their diffs read as pure movement rather than mixed move+reflow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Locks in the rustfmt baseline established by the previous commit so future drift surfaces at PR time. The check runs once on the ubuntu-latest matrix entry (fmt is platform-independent) and slots between the cargo cache and the platform deps install so a fmt regression fast-fails in seconds rather than after the apt-get pass. rustfmt joins the existing clippy component on the rust-toolchain step — both are cached via Swatinem/rust-cache so the marginal cost is the one-time component download on cache miss. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
"Platform support — early days" framed the gpui rewrite as fresh,
which fit v0.9.7-alpha but not v0.12 with four months of arm64
winget work, Scoop submissions, and shipped Windows boot fixes
behind it. The new wording mirrors TODO.md's canonical statement
("macOS is the primary dev / test target. Windows + Linux are
kept in mind in code, verified periodically — Linux less often
since gpui's Linux backend is the least-mature of the three.")
so the two stay in lockstep.
What changes for users reading a release page:
* Drop "early days" — the gpui line is past that bar.
* Drop "not yet routinely tested" for Windows — Windows builds
do get periodic real-hardware testing (the VCRedist regression
in 0.12.0, the boot fast-fail in 0.12.3, the USB-serial driver
detection work in the 0.11 line all came from real-hardware
sessions).
* Keep Linux honest — it's still the least-exercised of the
three, which TODO.md already calls out.
The disclaimer-block-drops-entirely TODO stays in the workflow
comment for the day all three platforms hit the macOS bar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`bundled_packs` used to `unwrap_or_else(panic!)` on any serde parse failure, so a single malformed JSON in the binary would abort boot before AppView ever rendered. The well-formedness invariant is already gated by the `bundled_packs_parse` unit test (and the project keeps clippy clean as CI policy), so the panic site existed for a class of failures that's caught by CI in practice — but absorbed by the user as "Baudrun won't launch" in the (vanishingly rare) cases where it does reach prod. Replace the panic with `log::error!` + skip-this-pack. The rest of the bundled set continues to load; the user sees their highlight options narrowed by one pack rather than facing an unlaunchable app. `baudrun-default` keeps its hard-fail invariant because `default_user_pack`'s `.expect` downstream still hard-stops on it (the user-pack seed depends on it being present), and that's the load-bearing pack we genuinely cannot recover from losing. No new test: the existing `bundled_packs_parse` already exercises this function fully and asserts the post-condition we care about (all bundled packs present and well-formed). The new path is defense-in-depth for a scenario the test suite catches before ship. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The `#![allow(dead_code, unused_imports)]` at the top of
`data/mod.rs` was a Phase-1 holdover from when the data layer
was ported from `src-tauri/src/` but not yet wired into any UI.
Phase 2 onwards consumed most of these modules — but the
blanket allow stayed put, masking new orphans accumulated during
the gpui rewrite. Narrowing it surfaces accidental dead code in
future PRs while preserving the intentional-orphan code we want
to keep buildable.
Module-status pass:
* File-level `#![allow(dead_code)]` on the modules that are
fully orphaned but worth keeping compiled as reference:
`serial/session.rs`, `serial/direct.rs`, `serial/usb_darwin.rs`,
`usbserial/mod.rs`, `usbserial/cp210x.rs`. These are the
Tauri-era libusb-direct serial path; the gpui code goes
`serialport`-only via `src/serial_io.rs`.
* File-level `#![allow(dead_code)]` + "candidate for full
deletion" note on Tauri-pure residue: `events.rs` (event-bus
constants) and `state.rs` (the old `AppState`/`SessionHandle`
keyed by Tauri window label). gpui's Entity/Global system +
`SettingsBus` replace both wholesale. Per the audit's
"flag, don't delete pre-existing dead code" rule I haven't
removed these — surfacing them here so a follow-up can.
* Item-level `#[allow(dead_code)]` / `#[allow(unused_imports)]`
on the singletons in otherwise-live modules:
`serial/mod.rs` (re-exports + `detect_missing_drivers`),
`serial/chipsets.rs::driver_url_for_vid`,
`highlight.rs::update_user_pack`,
`skins.rs::resolve`, `themes/mod.rs::resolve`. These ride in
actively-used modules so the file-level allow would over-
suppress — narrowing to the specific items keeps the rest of
each module honest.
* `data/mod.rs` itself: blanket allow removed, doc comment
refreshed to enumerate the status of each submodule so a
future reader doesn't have to grep the whole tree.
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four checks scoped to what's actually load-bearing for a binary
crate that pulls in a large Zed-git tree:
* advisories — RUSTSEC vulnerabilities + unmaintained warnings.
Four upstream-unmaintained transitive deps are listed in
`ignore =` with the dep chain + reason for each (paste,
rustls-pemfile, async-std, instant). All four trace into
gpui / gpui-component / image and can't be fixed without
upstream bumps; the ignore list documents what to revisit
when those land.
* licenses — explicit allow-list of GPL-3-compatible permissive
licenses (the project itself is GPL-3-or-later, so deps must
be compatible). Two per-crate exceptions for bzip2-1.0.6 and
NCSA; one clarify entry for `unescaper`'s deprecated
`GPL-3.0/MIT` SPDX form. Each one carries an explanation
rather than a bare crate-name allowance.
* bans — `multiple-versions = "warn"` because the Zed-git tree
duplicates windows-sys / bitflags / fastrand etc. across
versions and "deny" would block every PR. `wildcards = "warn"`
for the same reason: our four `git = "..."` deps register as
wildcards (no version constraint) and the Cargo.toml comment
on the gpui dep documents why we deliberately don't pin a rev.
* sources — `unknown-registry = "deny"` and `unknown-git = "deny"`
with `[sources.allow-org]` scoped to `zed-industries` and
`longbridge`. Org-level allow (not per-URL) because Zed pulls
in transitive deps from at least six sibling repos under
`zed-industries/*` and pinning the list per-URL would break
on every Zed bump.
The matching CI step lives on the ubuntu-latest matrix entry
only — cargo-deny reads Cargo.lock and is platform-independent,
so running it six times across the matrix would waste runner
minutes. taiki-e/install-action fetches a prebuilt binary
rather than building from source, ~3 min savings on cold runs.
`license = "GPL-3.0-or-later"` added to `[package]` so cargo-
deny's no-license-field warning doesn't fire on our own crate.
Informational-only since `publish = false`.
Verified: `cargo deny check` reports `advisories ok, bans ok,
licenses ok, sources ok` on a clean cache.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-split scaffolding. `app_view.rs` (7,235 lines) becomes `app_view/mod.rs` so subsequent commits can lift leaf concerns (session/window scaffolding, opts, buttons, chrome, editor, transfer) into sibling files without changing call sites — `crate::app_view::Foo` continues to resolve the same way. Pure rename: zero content change, identical compile output, `cargo clippy --all-targets -- -D warnings` and `cargo test` unchanged (63 tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lifts the small leaf concerns out of mod.rs:
* `SessionBundle` — the moved-between-windows live-session
container.
* `WindowInit` — the three-variant discriminator passed to
`open_app_window` (Fresh / WithSession / FreshAutoConnect).
* `geometry_to_bounds` / `bounds_to_geometry` — the
`WindowGeometry` ↔ `gpui::Bounds<Pixels>` helpers used by
`open_app_window`'s saved-bounds restore + the
`on_window_should_close` snapshot path.
Behaviour-preserving. `SessionBundle`'s fields stay package-
private to the `app_view` module via `pub(super)` so the parent's
`extract_session` / `install_session` methods continue to
construct and destructure it directly — the bundle is
intentionally a thin movable container, not a closed type with
constructors.
While I was here: reattached the orphan doc comment for
`open_app_window`, which had drifted into the gap between
`WindowInit` and the geometry helpers when those helpers were
inserted in an earlier change. It now sits where it belongs.
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lifts the window-construction entry point out of mod.rs into
`app_view::window`, re-exported as `app_view::open_app_window`
so main.rs's `use app_view::{open_app_window, AppView,
WindowInit};` continues to resolve without change.
Moves: `pub fn open_app_window` (~135 lines) + the
`TRAFFIC_LIGHT_POSITION_PX` const that backs its
`traffic_light_position` titlebar option.
The const stays shared with `AppView::open_settings_window` in
mod.rs (the Settings window uses the same traffic-light
position so the two windows feel uniform). Exposed via
`pub(super)` and re-imported into mod.rs by name.
`open_app_window` calls the still-private `AppView::connect_to`
and reads the still-private `AppView::profile_store` field from
its sibling module — that works without visibility widening
because Rust's privacy rule lets descendant modules see the
parent's private items (window.rs is a descendant of the
app_view module that defines AppView).
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`line_pill`, `pill_button`, `primary_button` move into a new `app_view::buttons` child module. All three are pure-style helpers (return a bare `gpui::Div` with no event handlers) used across the session header and the profile form, with no external callers outside `app_view`. Visibility: `pub(super)` on each so mod.rs imports them by name into its own namespace. `STATUS_DOT_PX` (consumed by `line_pill` for the status dot's diameter) stays private in mod.rs and reaches buttons.rs via Rust's descendants-see-parent-privates rule, same as the `connect_to` / `profile_store` access from window.rs. While here: reattached `pill_button`'s doc comment, which had slipped one slot up the file so it was sitting on top of `line_pill` instead. The fn definitions kept the wrong layout because both helpers have similar enough shape that the mis-doc didn't surface during reads. Verified: `cargo clippy --all-targets -- -D warnings` and `cargo test` both pass (63 tests, unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`struct Opt`, its `impl Opt` / `impl SelectItem`, the `make_select` / `read_select` wrappers, and every per-field option-list builder (baud, data_bits, parity, stop_bits, flow_control, line_ending, line_policy, backspace, port) move into a new `app_view::opts` child module. About 200 lines, all of which were a coherent profile-form helper layer. `Opt` keeps its fields private; only the `pub(super) fn new` constructor + the `SelectItem` impl reach across the module boundary. Same descendants-see-parent rule used for the earlier splits — opts.rs can call back into `super::AppView` for the `Context<AppView>` it needs in `make_select` / `read_select`. `port_opts` rides along because it returns the same `Vec<Opt>` shape and the editor composes it alongside the static lists, even though its data comes from `serial::ports::list_ports()` rather than a hardcoded table. The `pub use ...::ports` in mod.rs's import block drops out as a side effect — its only remaining user is now in opts.rs. Verified: `cargo clippy --all-targets -- -D warnings` and `cargo test` both pass (63 tests, unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lifts the 11 window-chrome / overlay helper functions out of
mod.rs into a new `app_view::chrome` child module:
* `profile_context_menu_overlay` + `profile_menu_item` — the
sidebar right-click popup and its single row primitive
* `suspended_banner` + `suspended_pane` — the two visual
treatments for a session in `Suspend` mode
* `about_dialog_body` — content for the About dialog
* `friendly_open_error` — serial-open error string formatter
(the only non-rendering helper in the file; lives here
because every caller is a render-time error path)
* `welcome_pane` — the empty-state shown at boot with no
connected profile
* `session_header` + `status_bar` + `session_overflow_button` —
the top toolbar, bottom status row, and `⋯` overflow menu
* `sidebar_header` + `sidebar_icon_strip` — the two layouts
for the left sidebar (expanded vs. collapsed)
All eleven are `pub(super)` so mod.rs imports them by name.
Internal cross-references (e.g. `session_overflow_button` calling
`profile_menu_item`) stay private. The trailing comment block
about chrome consts having migrated to `SkinTokens` rides along
with the chrome code so the historical note keeps its proximity
to the helpers it describes.
While here: rolled `session_overflow_button` (which had stayed
in mod.rs after the earlier Phase D split) into chrome.rs since
it's an inline child of `session_header` and shares the same
popup-paint pattern as `profile_context_menu_overlay`. Cleans up
the `use buttons::{line_pill, ...}` line on mod.rs too —
`line_pill` was only used by `session_header`, which now lives
in chrome.rs.
mod.rs drops by ~990 lines (6,643 → 5,651). chrome.rs lands at
1,032 lines — large but cohesively scoped to "render-time
chrome subtree producers."
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lifts the profile-editor form rendering + state-bridging out of
mod.rs into a new `app_view::editor` child module. About 1,400
lines covering:
* `build_editor` / `apply_editor_to_profile` — the bidirectional
bridge between a `Profile` and the live form widget state.
* `editor_fields_match` — dirty-check predicate that drives the
Save button's brightness.
* `EditorRender` + its `from(&Editor, &Context)` constructor —
the cloned-out widget handles a render pass needs, so the
render code can hand `cx: &mut Context<AppView>` to form
helpers without keeping `&self.editor` borrowed alongside.
* `form_pane` — the public entry; called from `Render for AppView`.
* `form_header`, `form_body`, `form_tab_nav`, `section_card`,
`section_card_with_desc`, `labeled`, `bool_field`,
`bool_field_hinted`, `connection_card`, `terminal_card`,
`highlighting_pane`, `advanced_pane`, `theme_card`,
`control_lines_card`, `output_card`, `paste_safety_card` —
the internal helpers that compose the form's visual tree.
* `detect_missing_drivers` + `driver_banner_row` — the
unenrolled-USB-driver warning shown above the Serial Port
field; only the form renders this so it lives here.
Visibility plan: `pub(super)` on the four items mod.rs actually
references (`build_editor`, `apply_editor_to_profile`, `form_pane`,
`struct EditorRender` + `EditorRender::from`). The rest stay
private — `form_header` / `form_body` / etc. are only ever called
from within editor.rs.
`struct Editor` + `enum EditorTab` stay in mod.rs because the
parent's methods on `AppView` (set_editor_tab, save_editor,
toggle_local_echo, …) do direct field access on Editor, and the
descendants-see-parent-private rule means editor.rs can still
read those fields without per-field `pub(super)` widening. The
split is along "form rendering & state-bridging logic" lines
rather than "Editor data type and friends."
mod.rs drops by ~1,395 lines (5,651 → 4,256). editor.rs lands at
1,441 lines — large, but every item is part of the editor form
pipeline.
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lifts the Send-File-specific UI primitives out of mod.rs:
* `YMODEM_PROTOCOL_ID` + `transfer_protocol_opts` — the
Select widget's default pick + option list.
* `send_file_field_label`, `send_file_path_pill`,
`send_file_choose_button`, `send_file_secondary_button`,
`send_file_primary_button` — dialog-specific pill/button
helpers. Kept separate from the generic `buttons.rs`
primitives because they have distinct sizing + spacing
(Send File uses a wider px_4 / py(6.0) button vs the
generic px_3 / py_1).
Module name is `transfer_ui` rather than `transfer` to avoid
shadowing `crate::data::transfer`, which mod.rs's transfer
state-machine driving (`send_xmodem`, `send_ymodem`, etc.)
imports as `transfer::`. The `_ui` suffix accurately names the
content (Send-File-dialog UI helpers) rather than the broader
transfer concept.
The transfer **types** (`TransferIo`, `TransferState`,
`TransferResult`, `SendHexState`, `SendFileState`) stay in
mod.rs. Their fields are accessed across ~20 AppView methods
that drive the transfer state machine; moving them would force
13+ `pub(super)` field-visibility widenings for no functional
gain. The split here is "render helpers only" — same rationale
as keeping `Editor` in mod.rs while moving the form rendering.
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-split scaffolding. `settings_view.rs` (3,826 lines) becomes `settings_view/mod.rs` so subsequent commits can lift leaf concerns (shortcuts marshalling, theme preview, generic controls) into sibling files without changing call sites — `crate::settings_view::SettingsView` / `settings_view::SHORTCUT_ACTIONS` / `settings_view::effective_shortcut` / `settings_view::spec_to_gpui_binding` all continue to resolve the same way. Pure rename: zero content change, identical compile output, `cargo clippy --all-targets -- -D warnings` and `cargo test` unchanged (63 tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…g into shortcuts.rs
Lifts the entire "shortcuts data + keystroke spec marshalling"
section out of mod.rs into `settings_view::shortcuts`:
* Public surface (re-exported as `settings_view::*`):
- `SHORTCUT_ACTIONS` (canonical id list, display order)
- `effective_shortcut(action, overrides)` (resolves a row's
live binding, honouring overrides over per-OS defaults)
- `spec_to_gpui_binding(spec)` (Tauri-style spec →
gpui keybinding string for `cx.bind_keys`)
* `pub(super)` helpers used by `SettingsView` itself:
- `shortcut_label` (display label per action id)
- `format_spec(&Keystroke)` (Tauri-style spec for persistence)
- `parse_spec(spec)` (reverse, for rendering the live pill)
- `any_modifier(&Modifiers)` (recording-state Escape gating)
* Module-private:
- `default_for_action` (per-OS — two cfg-gated copies)
- `canonical_key_for_storage` / `canonical_key_for_display`
(normalisation between gpui key names and Tauri storage)
Visibility plan keeps the original `pub(crate)` for the three
items main.rs consumes via `settings_view::*`, narrows the four
internal helpers to `pub(super)`, and leaves the helpers used
only inside shortcuts.rs unannotated.
mod.rs drops by ~315 lines (3,763 → 3,452). The
`std::collections::HashMap` + `gpui::{Keystroke, Modifiers}`
imports come out of mod.rs along with the moved code — no
remaining caller named those types.
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ew.rs
Lifts the theme rendering helpers out of mod.rs into a new
`settings_view::theme_preview` child module:
* `pub(super)` entry points:
- `theme_swatches(&Theme)` — compact 8-color strip rendered
at the left of each installed-themes row.
- `theme_preview_block(&Theme)` — full-fidelity preview
dialog body, sample lines + paired fg/bg blocks.
* Module-private helpers:
- `preview_sample_lines()` — the canned sample-output rows
the preview block renders against each theme's palette.
- `parse_theme_color(&str)` — `#RRGGBB` / `#RGB` / `#RRGGBBAA`
→ `0xRRGGBBAA` u32 used by gpui's `rgba`.
About 235 lines of self-contained colour-rendering code that
has no callers outside `settings_view`. The `SharedString`
import comes along on theme_preview.rs (used inline by
`theme_preview_block`); the `gpui::SharedString` line stays in
mod.rs because settings_view's keystroke-capture path still
needs it.
mod.rs drops by ~235 lines (3,452 → 3,215).
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…chrome.rs
Lifts the structural chrome + reusable form controls out of
mod.rs into a new `settings_view::chrome` child module. About
475 lines covering 11 `pub(super)` helpers:
* Window structure: `window_header`, `rail`, `scrollable_pane`,
`section_card_with_desc`, `bool_field`.
* Generic affordances: `dismiss_notification_after`,
`encode_file_path`, `resolve_config_dir_display`,
`import_button`, `trash_button`, `make_select`.
Two pre-existing doc-comment layout bugs surfaced and got
fixed along the way:
* `dismiss_notification_after`'s doc was duplicated inline
(6 lines of "Schedule a Notification…" repeated verbatim,
pre-existing in mod.rs at HEAD). De-duplicated in the move,
single clean copy now lives above the fn in chrome.rs.
* `import_button`'s doc had drifted up into the gap between
`bool_field` and the `SECTION_KEYWORDS` const in HEAD, so
`import_button` itself rendered undocumented. Reattached
to the actual fn in chrome.rs.
The taxonomy consts (`SECTION_KEYWORDS`, `TAB_SECTIONS`) stay
in mod.rs because they're data tables consumed by
`SettingsView`'s filter logic rather than chrome primitives —
moving them would force `pub(super)` widenings on
`SettingsTab` enum variants for no functional gain.
mod.rs drops by ~480 lines (3,215 → 2,734).
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The winget validator's headless arm64 sandbox can't initialize a Direct3D device, so gpui's renderer init returns `DXGI_ERROR_NOT_CURRENTLY_AVAILABLE` (`0x887A0022`). That used to fast-fail under `panic = "abort"` (caught in v0.12.2 → fixed in 535b7ec by handling the Err) but even after the v0.12.3 + v0.12.4 fixes that landed the dialog + skipped `cx.quit()`, a deeper `AsyncApp::update_entity` panic still fires during cleanup of state set up before the failed window open (`gpui_component::init`, the settings-bus subscribe). That kept arm64 out of v0.12.4's winget submission (microsoft/winget-pkgs#377461). Path B from the audit's winget triage: probe D3D11 before any gpui state exists. Inline FFI on `D3D11CreateDevice` (d3d11.dll), matching the shape of `show_window_open_error_dialog`'s `MessageBoxW` FFI and `detect_reduce_motion`'s `SystemParametersInfoW` FFI — avoids a direct `windows-sys` dep that'd conflict with gpui_windows's transitive version on every gpui bump. All ten out-args pass null because we don't want the device, just the HRESULT. On failure the process pops the same Windows error dialog flavour as the existing fallback (caption + MessageBoxW) and exits with code 0. The winget validator's 10-second launch test accepts either a clean exit OR a still-running process — both outcomes satisfy the validator, but the clean-exit path doesn't run any gpui cleanup code so there's no RefCell to re-borrow and no `STATUS_STACK_BUFFER_OVERRUN` to record. Trade-offs: * Real-user UX on a genuinely broken GPU: same dialog, but the process now exits cleanly after dismissal rather than zombie- idling the empty event loop. Net better for users. * Probe overhead: one `D3D11CreateDevice` call per launch on Windows (~milliseconds on a healthy machine). Negligible. * MessageBoxW duplicates the FFI declaration from `show_window_open_error_dialog`. Two call sites is on the edge; if a third lands, refactor into a private `show_error_dialog` helper. Doc comment flags the threshold. * The existing `match open_app_window(...)` error path stays — the probe specifically catches the validator's no-adapter-at-all case, but non-DXGI window-open failures can still happen and need the safety net. Followup once a real Windows-arm runner verifies the probe works: restore arm64 to the winget manifest (TODO.md's "arm64 winget submission" item) and ship the next stable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an on-demand trigger to release.yml so we can produce a
windows-arm64 build of a feature branch without tagging a
pre-release. Primary motivation: verify the DXGI probe (added in
the previous commit) on a real Windows-arm host before merging
the audit branch to main and tagging v0.12.5.
Surface:
* `workflow_dispatch` with a single required `version` input
(default `0.0.0-dev`). A hyphen in the value is treated as a
pre-release marker the same way a tag would be, so MSI
building is skipped — `ProductVersion` rejects alphanumeric
segments and would fail the build. The bare .exe + NSIS
installer + portable .zip still ship, which is what the probe
test path actually needs.
* Workflow-level `env.EFFECTIVE_VERSION` resolves the dispatch
input or falls through to `github.ref_name`. All
version-derivation sites (5 bash, 2 PowerShell, 3 pre-release
`if:` gates, 1 GitHub-Release `prerelease:` flag) read this
instead of `GITHUB_REF_NAME` so the dispatch path works
without per-step plumbing.
* The `release` job is gated to `github.event_name == 'push'`
so workflow_dispatch runs DON'T create a GitHub Release.
Artifacts land on the workflow-run page only (90-day
retention, `gh run download <run-id>` for CLI access),
keeping the Releases page uncluttered for ad-hoc testing.
GitHub only shows the "Run workflow" button if the trigger lives
on the default branch. This commit ships the trigger so the
audit branch can be tested via dispatch once it (or just this
commit, cherry-picked) lands on main.
The release notes step's `CURRENT_TAG="${GITHUB_REF_NAME}"` at
the release job stays unchanged — it lives in the job that's
gated to push events only, so `GITHUB_REF_NAME` is always a tag
there.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same hygiene pass the root crate got in 7743a8e (Phase 1 of the audit), now applied to the two helper crates under scripts/: * scripts/virtual-serial — the Rust virtual-serial test rig used by the manual smoke playbook in scripts/virtual-serial/TESTING.md. * scripts/transfer-tests — the automated wire-level XMODEM / YMODEM harness. These aren't part of cargo's workspace (each has its own Cargo.toml; the root crate doesn't `members =`), so the root `cargo fmt` invocation skipped them, and the `cargo fmt --check` CI step added in 96dfacf was checking only the root crate. Two changes here: * Apply `cargo fmt` once to bring both scripts crates to the rustfmt baseline. ~240 lines reformatted across three files, pure whitespace + line-wrap normalisation; no behaviour or logic changes (these are dev-only tools that aren't built in the main binary, but `cargo build` per directory still succeeds — same code path the manual transfer-test runs exercise). * Extend the CI step (still on ubuntu-latest only) to loop over scripts/*/ and run `cargo fmt --check` in each. Same fast-fail placement before the platform deps install. New step name reflects the broader scope. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The branch CI's first dispatch run failed on the two Ubuntu matrix entries with six dead-code errors in `serial::chipsets`: ChipsetInfo, needs_driver, identify, is_suspect_product, rebrand_for, chipset_from_manufacturer. macOS / Windows pass because the consumers (`serial::detect`, `serial::usb_darwin`, `serial::usb_windows`) ARE compiled on those platforms — but all three of those modules are `#[cfg(any(target_os = "macos", target_os = "windows"))]` per the `pub mod` declarations in `serial/mod.rs`, so on Linux every chipsets item is unreachable. I missed this in 247f7e4's narrowing pass — I only added an item-level allow to `driver_url_for_vid` because the rest of the file looked actively wired, not realising the wiring is platform-conditional and Linux gets no callers. Fix: * File-level `#![allow(dead_code)]` on chipsets.rs, with a doc-comment paragraph naming the platform-conditional callers so a future reader doesn't re-stumble into the same narrowing trap. Matches the pattern used by `usb_darwin`, `cp210x`, `direct`, `usbserial::mod` — the other modules in the same dead-on-Linux cluster. * Drop the now-redundant item-level `#[allow(dead_code)]` on `driver_url_for_vid`; the file-level one subsumes it. * `data/mod.rs` module-status comment: move `serial::chipsets` out of the "actively wired on all platforms" bucket into the "dead on Linux" bucket alongside the other libusb-direct siblings, with the same callsite explanation. Verified locally on macOS (`cargo clippy --all-targets -- -D warnings` + `cargo test` both clean) but the original failure mode was Linux-only, so the actual confirmation comes from the next dispatch run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Surfaces a concrete user pain point flagged during the audit
branch's CI verification: the libusb-direct CP210x backend under
`src/data/usbserial/cp210x.rs` is fully implemented but not
wired into `serial_io::open`, so a Siemens RuggedCom RST2228
(CP210x rebrand at VID 0x0908 / PID 0x01FF, already in the
`REBRANDS` table) doesn't enumerate on macOS without SiLabs'
VCP kext installed — and the user can't connect.
The Tauri build had this fallback wired; the gpui rewrite went
`serialport`-only and never restored it. Code, tests, and
chipset table all carried forward intact; the missing piece is
the dispatch in `serial_io::open` ("OS port not found" branch
delegates to `usbserial::cp210x::open_port`) plus surfacing the
libusb-direct ports under the existing `usb:VID:PID:Serial`
name scheme that `data::serial::direct` defines.
Entry lands at the top of "Serial features (next tranche)"
without the **[on request]** marker — this isn't a hypothetical
feature ask, it's a real user with affected hardware.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both modules existed solely as consequences of Tauri's two-process
architecture (Rust backend ↔ JS frontend over IPC). gpui collapses
that into a single Rust process where UI + state share memory, so
both indirection layers became redundant on the rewrite:
* `events.rs` — event-bus name constants (`"serial:data"`,
`"settings:updated"`, etc.) + `TransferProgress` payload. The
bus existed because the Rust serial read thread couldn't poke
the xterm.js renderer directly. Replaced wholesale by direct
`flume` channels into gpui entities + `SettingsBus`'s
`cx.subscribe`/`cx.emit` pair.
* `state.rs` — `AppState` singleton + `Mutex<HashMap<window_label,
SessionHandle>>` + cross-window pending-payload HashMaps. The
string-key indirection existed because Tauri commands address
windows by label, and cross-window data handoff (terminal
snapshots for session migration, initial profile ids for new
windows) couldn't be passed by reference across the IPC
boundary. Replaced by per-window state living on `AppView`
directly + `AppShared` global for cross-window stores +
`WindowInit::WithSession(SessionBundle)` for direct entity
handoff at window-creation time.
247f7e4 flagged both as deletion candidates and gave them
file-level `#![allow(dead_code)]` to keep them compiling while
documented. Confirmed zero in-tree callers
(`grep -rn "data::events\|data::state\|TransferProgress\|AppState\|SessionHandle"`
returns nothing outside the deleted files), so the deletion is
mechanical — no follow-up wiring needed.
`data/mod.rs`'s status comment loses the "Tauri-era residue"
bullet and gains a closing note explaining what was removed +
why, so a future reader who finds an old git ref pointing at
the deleted files can still understand the architectural shift.
Verified: `cargo clippy --all-targets -- -D warnings` and
`cargo test` both pass (63 tests, unchanged).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Completes the scripts/* CI gate started in 4620d73 (which added the fmt --check loop). That commit caught style drift but didn't verify the scripts still compile — so a shared type change in `src/data/transfer.rs` could break `scripts/transfer-tests` silently, since the root `cargo clippy` / `cargo test` skip the scripts/* crates entirely (they're not cargo workspace members). Runs as the last step on the existing ubuntu-latest gate (co-located with fmt + deny). ubuntu-only because the scripts target Unix and the apt-get step earlier in the matrix already installs libudev for serialport. Cold compile is ~30 s per crate (small dep trees — `serialport`, `ctrlc`, `serde`; no `gpui`); incremental is a few seconds courtesy of Swatinem/rust-cache. Doesn't ship the compiled binaries — pure compile verification. The actual transfer-tests + virtual-serial workflows still live under CONTRIBUTING.md's "Running tests" section as manual runs from source. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Surfaces the v0.12.5 user-facing change so the next stable release's auto-generated notes pick it up. Continues the v0.12.3 + v0.12.4 boot-fix story: each prior fix uncovered the next panic layer; the probe sidesteps the whole class by ensuring no gpui state exists on the failure path. Wording mirrors v0.12.3 / v0.12.4's entry shape (problem, what v0.12.5 changes, what the user sees, validator-context note, PR link). Pre-emptively cross-references microsoft/winget-pkgs #377461 so a future reader following the story from CHANGELOG can pull the validator's actual failure transcript. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The audit branch landed the DXGI probe (9fbfb9d) that fixes the specific RefCell reentrancy the winget validator's headless arm64 sandbox tripped on v0.12.2 / v0.12.3 / v0.12.4. Captures the state + ship sequence so future work doesn't re-derive what's already fixed. The entry is fresh on this branch — main + chore/audit don't carry the equivalent "deferred arm64 winget submission" entry that lives on docs/winget-install (commit 008c38c). Eventual merge of docs/winget-install can drop its now-stale entry in favour of this one, or reconcile in the merge. Lives under ## Distribution next to the (completed) arm64 MSI entry it logically follows — both are sequential steps in getting arm64 winget users a native binary instead of the current x64-via-emulation fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tips the call I left on the edge in 9fbfb9d. That commit's doc flagged "two call sites is on the edge — if a third lands, the FFI should move into a private helper." With both call sites already in the tree (`show_window_open_error_dialog` from v0.12.3 + `show_dxgi_unavailable_dialog` from this branch's probe), the duplication is ~30 lines of identical wide-string + MessageBoxW FFI per caller. Extracting now removes the duplication AND removes the "on the edge" framing. New shape: * `show_windows_error_dialog(caption: &str, body: &str)` — owns the OsStr-to-UTF-16 wide-string conversion, the MessageBoxW FFI declaration, and the `MB_OK | MB_ICONERROR` flags. Same doc block as the previous `show_window_open_error_dialog` explaining why inline FFI (no `windows-sys` dep), why the dialog doubles as a validator launch-test signal, etc. * `show_window_open_error_dialog<E: Debug>(err: &E)` — builds its body with the err interpolated, delegates. Loses its duplicate FFI block. * `show_dxgi_unavailable_dialog(hr: u32)` — builds its body with the HRESULT interpolated, delegates. Loses its duplicate FFI block. Net: ~75 lines of duplicated FFI/wide-string boilerplate collapses into a single ~40-line helper + two ~15-line body-building callers. Same behaviour, easier to maintain (future MessageBoxW flag tweaks, dialog title changes, or wide-string handling fixes touch one place). Updated `dxgi_probe`'s doc comment to reference `show_windows_error_dialog` instead of the now-thinner `show_window_open_error_dialog` for the inline-FFI shape precedent. Verified locally on macOS (`cargo clippy --all-targets -- -D warnings` + `cargo test` both clean); Windows code is cfg-gated so CI will verify the actual MessageBoxW compile on the next dispatch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 tasks
3 tasks
packetThrower
added a commit
that referenced
this pull request
May 24, 2026
Moves the DXGI probe entry from [Unreleased] into a versioned [0.13.0] section dated today (the day all four PRs landed on main: #38 audit + probe, #39 macos-15-intel drop, #36 gpui bump that subsumed #37 gpui_platform bump). Adds a [Changed] entry for the gpui upstream-rev bump. Per CONTRIBUTING.md, dev-tool / internal-refactor changes stay out of CHANGELOG — the file splits, cargo-deny, workflow_dispatch, fmt + scripts CI gates, Tauri-residue deletion all land in the audit but don't surface to users beyond "things compile + run as before." git log carries the per-commit detail for anyone spelunking; the CHANGELOG entry is what shows up in the GitHub Release body. The release date is set to today (2026-05-24) since that's when the v0.13.0 content was finalized on main. If the stable tag lands days after the beta, the date can be bumped — but since all content is already merged, today is the accurate "this is what the release contains" anchor. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
app_view.rs(7,235 → 4,127 LOC) andsettings_view.rs(3,826 → 2,733 LOC) into per-concern sibling modules; narrowed module-wideallow(dead_code); deleted Tauri-era residue (events.rs,state.rs); applied cargo-fmt baseline + added CI fmt-check + cargo-deny supply-chain audit + scripts/* compile-verification step.main.rs::dxgi_proberuns before any gpui state exists. On failure pops the same Windows error dialog flavour and exits 0 — bypasses the cleanup-timeAsyncApp::update_entityRefCell panic that kept arm64 out of v0.12.4's winget submission (microsoft/winget-pkgs#377461).workflow_dispatchtrigger onrelease.ymlfor ad-hoc arm64 builds without tagging. Cherry-picked separately to main earlier so this branch can be dispatched while in PR.Test plan
cargo clippy --all-targets -- -D warningsclean on every commit (local macOS)cargo test— 63 passing on every commit, no test count changecargo deny check— advisories / bans / licenses / sources all okBaudrun.exelaunches normally on Windows 11 arm in UTM (happy path)Each commit is independently buildable + tested; bisecting remains useful across the branch.
Out of scope (follow-ups)
packaging/windows/winget/packetThrower.Baudrun.installer.yaml.template— happens after this lands, v0.12.5 is cut, and the arm64.msiships. Full sequence captured in TODO.md's new "Re-include arm64 in the winget submission" entry.data::usbserial::cp210xlibusb-direct backend still not wired intoserial_io::openas a fallback —chore/auditflagged this via a TODO.md entry after the user surfaced the Siemens RuggedCom RST2228 use case. Separate work item, not part of this branch.🤖 Generated with Claude Code