fix(gui): Qt transcript overlay correctness, lifecycle & bridge wiring#416
fix(gui): Qt transcript overlay correctness, lifecycle & bridge wiring#416Coldaine wants to merge 7 commits into
Conversation
Summary of changes: - Fixed GuiBridgeRust type path and struct definition in bridge.rs. - Refactored cmd_start to properly manage the background STT pipeline, storing the AppHandle and STT task handle in the bridge. - Implemented graceful shutdown in cmd_stop and cmd_clear by calling app.shutdown(). - Updated the default STT plugin selection to "moonshine" (replacing the deprecated "whisper"). - Fixed transcript formatting to avoid leading newlines on the first finalized transcript append. - Aligned CXX-Qt property types and setters in bridge.rs to use String consistently, resolving type mismatch issues. - Updated crates/coldvox-gui/Cargo.toml to use the "moonshine" feature for coldvox-app. - Enhanced main.rs to establish a Tokio runtime context for the GUI application. These changes address all unresolved reviewer feedback from PR #387 regarding lifecycle handling, correctness, and type safety. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Qt Overlay Fixes: - Corrected GuiBridgeRust type path and struct definition in bridge.rs. - Refactored cmd_start to properly manage the background STT pipeline, storing the AppHandle and STT task handle in the bridge for robust lifecycle management. - Implemented graceful shutdown in cmd_stop and cmd_clear by calling app.shutdown(). - Updated the default STT plugin selection to "moonshine". - Fixed transcript formatting to avoid leading newlines on the first entry. - Aligned CXX-Qt property types and setters in bridge.rs to use String consistently. - Updated crates/coldvox-gui/Cargo.toml to use the "moonshine" feature for coldvox-app. - Enhanced main.rs to establish a Tokio runtime context for the GUI application. Documentation & CI Fixes: - Added required frontmatter metadata to docs/architecture/adr-0001.md, docs/playbooks/telemetry/tele-observability-playbook.md, and several history log files. - Relocated files to their canonical locations under /docs to satisfy placement rules. - Verified all documentation changes using the scripts/validate_docs.py tool. These changes address unresolved review comments from PR #387 and resolve CI failures in the documentation validation job. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Refactored `GuiBridgeRust` in `crates/coldvox-gui/src/bridge.rs` to include `app_handle` and `stt_task` for robust lifecycle management. - Initialized a multi-threaded Tokio runtime in `crates/coldvox-gui/src/main.rs` to support async tasks within the GUI. - Replaced `std::thread::spawn` with `tokio::spawn` for STT pipeline initialization. - Switched default STT plugin selection to "moonshine". - Implemented graceful pipeline shutdown in `cmd_stop` and `cmd_clear` using `AppHandle::shutdown()`. - Aligned FFI property setters and signal types from `QString` to `String` to prevent FFI mismatches. - Fixed transcript formatting logic to avoid leading newline insertion on the first entry. - Corrected `GuiBridge` type path for CXX-Qt 0.7 compatibility. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Implement robust lifecycle management in `GuiBridgeRust` by storing `AppHandle` and STT task handles. - Initialize Tokio runtime in GUI entry point to support async operations. - Switch default STT plugin to "moonshine" and fix FFI type bindings (String vs QString). - Resolve RUSTSEC-2026-0007 (bytes), RUSTSEC-2026-0009 (time), and RUSTSEC-2026-0067/68 (tar) by updating dependencies. - Fix linting errors (unused imports and variables) and formatting issues in `coldvox-text-injection` and `coldvox-stt`. - Update `Cargo.lock` to align with dependency changes and satisfy CI `--locked` checks. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
QML / Bridge fixes: - AppRoot.qml: replace non-existent bridge.level with local int 0 - AppRoot.qml: replace non-existent bridge.transcript with computed displayTranscript from bridge.partial_transcript + bridge.final_transcript - AppRoot.qml: replace bridge.toggle_expand() (no such invokable) with direct bridge.expanded = !bridge.expanded property write (3 sites) - AppRoot.qml: replace bridge.cmd_toggle_pause() with inline state check delegating to cmd_pause / cmd_resume based on AppState value - AppRoot.qml: remove demo timer block referencing non-existent bridge.demo_set_level / bridge.demo_append_delta - SettingsWindow.qml: add missing property real opacityValue: 0.3 and wire Slider.onMoved so AppRoot's Connections handler can observe changes - Main.qml: bind st to bridge.state via typeof guard (was always 0) - Main.qml: call scroll.scrollToBottom() on both transcript text changes bridge.rs: - Error path in cmd_start now queues state=Error and last_error to the Qt thread; previously the state stayed Activating/Active on failure Rust feature gating (STT pipeline not restricted to whisper): - stt/mod.rs: gate processor and persistence on any(whisper, parakeet) - runtime.rs: gate all STT pipeline cfg attrs on any(whisper, parakeet) - tui.rs: gate TranscriptionEvent cfg attrs on any(whisper, parakeet) Plugin manager (Codex P1/P2): - Remove silently dropped load_config() future from synchronous constructor - Await load_config() at the async construction site in runtime.rs instead - GC sweep now excludes the currently active plugin before building the inactive list, preventing active plugin eviction Dependencies: - Move zbus to Linux-only target dependency (was unconditional, breaking Windows/macOS builds that don't have DBus) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 289 files, which is 139 over the limit of 150. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (11)
📒 Files selected for processing (289)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR migrates the coldvox-gui crate from the prior Tauri/React overlay shell to Qt 6 + QML (CXX-Qt) scaffolding, while also adjusting STT/text-injection/audio plumbing and CI setup to support the new direction and improve build portability.
Changes:
- Replaced the
coldvox-guiTauri/React implementation with a feature-gated Qt/QML UI and added new QML components for overlay behavior. - Updated audio/STT/text-injection crates (deps, feature gates, and tests) to align with new build goals and platform constraints.
- Introduced a new “minimal” CI workflow and refactored docs/dev tooling references.
Reviewed changes
Copilot reviewed 157 out of 343 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/coldvox-text-injection/src/tests/test_harness.rs | Simplifies process spawning in test harness. |
| crates/coldvox-text-injection/src/tests/mod.rs | Adjusts which text-injection test modules are compiled. |
| crates/coldvox-text-injection/src/prewarm.rs | Tweaks prewarm timing variables/attributes and logging imports. |
| crates/coldvox-text-injection/src/manager.rs | Adjusts backend detector dead-code allowance and test assertions. |
| crates/coldvox-text-injection/src/injectors/clipboard.rs | Changes test cfg gating for stdin execution tests. |
| crates/coldvox-text-injection/src/injectors/atspi.rs | Cleans up unused params/timing vars and conditional imports. |
| crates/coldvox-text-injection/src/confirm.rs | Refactors timing vars and conditional imports for confirmation logic. |
| crates/coldvox-text-injection/examples/test_enigo_live.rs | Simplifies config creation for enigo live example. |
| crates/coldvox-text-injection/build.rs | Changes how the terminal test app is built. |
| crates/coldvox-text-injection/Cargo.toml | Adjusts dependency versions in text-injection crate. |
| crates/coldvox-telemetry/src/integration.rs | Changes how STT metrics counters are incremented/recorded. |
| crates/coldvox-stt/src/plugins/moonshine.rs | Updates PyO3 GIL API usage and compatibility. |
| crates/coldvox-stt/src/plugins/mod.rs | Reorganizes STT plugin modules under feature gates. |
| crates/coldvox-stt/src/plugin.rs | Removes runtime validation helper and changes default fallbacks. |
| crates/coldvox-stt/examples/verify_moonshine.rs | Removes the Moonshine verification example. |
| crates/coldvox-stt/README.md | Rewrites README to be more engine-agnostic and updates examples. |
| crates/coldvox-stt/Cargo.toml | Adjusts versions/features; changes PyO3/tempfile versions. |
| crates/coldvox-gui/vitest.setup.ts | Removes Vitest setup (Tauri/React stack removal). |
| crates/coldvox-gui/vitest.config.ts | Removes Vitest config (Tauri/React stack removal). |
| crates/coldvox-gui/vite.config.ts | Removes Vite config (Tauri/React stack removal). |
| crates/coldvox-gui/tsconfig.json | Removes TS config (Tauri/React stack removal). |
| crates/coldvox-gui/src/main.tsx | Removes React entrypoint. |
| crates/coldvox-gui/src/main.rs | Adds Qt/QML runtime entrypoint gated by qt-ui. |
| crates/coldvox-gui/src/lib/overlayBridge.ts | Removes Tauri invoke/listen bridge layer. |
| crates/coldvox-gui/src/hooks/useOverlayShell.ts | Removes React hook shell for overlay state. |
| crates/coldvox-gui/src/hooks/useOverlayShell.test.tsx | Removes Vitest/RTL test for overlay hook. |
| crates/coldvox-gui/src/contracts/overlay.ts | Removes TS contract types for overlay. |
| crates/coldvox-gui/src/components/StatusPill.tsx | Removes React status pill component. |
| crates/coldvox-gui/src/components/OverlayShell.tsx | Removes React overlay shell component. |
| crates/coldvox-gui/src/components/OverlayShell.test.tsx | Removes React overlay shell tests. |
| crates/coldvox-gui/src/App.tsx | Removes React app wrapper. |
| crates/coldvox-gui/src-tauri/tauri.conf.json | Removes Tauri configuration. |
| crates/coldvox-gui/src-tauri/src/window.rs | Removes Tauri window sizing logic. |
| crates/coldvox-gui/src-tauri/src/main.rs | Removes Tauri main entrypoint. |
| crates/coldvox-gui/src-tauri/src/demo.rs | Removes Tauri demo script driver. |
| crates/coldvox-gui/src-tauri/src/contract.rs | Removes Tauri Rust-side overlay contract. |
| crates/coldvox-gui/src-tauri/gen/schemas/capabilities.json | Removes generated capabilities schema. |
| crates/coldvox-gui/src-tauri/capabilities/default.json | Removes Tauri capabilities file. |
| crates/coldvox-gui/src-tauri/build.rs | Removes Tauri build script. |
| crates/coldvox-gui/src-tauri/Cargo.toml | Removes nested Tauri crate manifest. |
| crates/coldvox-gui/qml/SettingsWindow.qml | Adds settings window UI and opacity property. |
| crates/coldvox-gui/qml/ControlsBar.qml | Adds expanded-mode controls bar component. |
| crates/coldvox-gui/qml/CollapsedBar.qml | Adds collapsed-mode UI component. |
| crates/coldvox-gui/qml/AppRoot.qml | Adds top-level QML overlay window and wiring. |
| crates/coldvox-gui/qml/ActivityIndicator.qml | Adds animated activity indicator. |
| crates/coldvox-gui/qml/ActivePanel.qml | Adds expanded panel with transcript + controls. |
| crates/coldvox-gui/package.json | Removes npm-based GUI scaffolding. |
| crates/coldvox-gui/justfile | Updates just commands for Qt build/run. |
| crates/coldvox-gui/index.html | Removes web UI HTML entrypoint. |
| crates/coldvox-gui/build.rs | Adds CXX-Qt build script gated by qt-ui. |
| crates/coldvox-gui/README.md | Updates GUI README to reflect Qt direction and prototype scope. |
| crates/coldvox-gui/Cargo.toml | Introduces new Qt/CXX-Qt feature-gated Rust crate manifest. |
| crates/coldvox-foundation/src/test_env.rs | Loosens test assertions around available command detection. |
| crates/coldvox-foundation/src/env.rs | Simplifies env-var manipulation in tests. |
| crates/coldvox-foundation/Cargo.toml | Adjusts tokio/cpal/dev-deps versions. |
| crates/coldvox-audio/tests/windows_live_mic_test.rs | Removes Windows live mic tests. |
| crates/coldvox-audio/tests/windows_live_capture_test.rs | Removes Windows live capture tests. |
| crates/coldvox-audio/tests/live_audio_capture_test.rs | Removes live audio capture test suite. |
| crates/coldvox-audio/src/resampler.rs | Switches resampler implementation to rubato 0.16 SincFixedIn. |
| crates/coldvox-audio/src/lib.rs | Removes StreamResampler re-export from public API. |
| crates/coldvox-audio/src/device.rs | Updates device naming and sample-rate API usage for cpal 0.16. |
| crates/coldvox-audio/src/capture.rs | Adds preallocation + debug assertions in audio conversion buffers. |
| crates/coldvox-audio/examples/live_capture.rs | Removes live capture example. |
| crates/coldvox-audio/Cargo.toml | Downgrades deps (cpal/rubato/tokio/libc) and removes feature flag. |
| crates/coldvox-audio-quality/test_data/README.md | Removes audio quality test data docs. |
| crates/coldvox-audio-quality/src/types.rs | Removes audio quality types module. |
| crates/coldvox-audio-quality/src/lib.rs | Removes audio quality crate root. |
| crates/coldvox-audio-quality/benches/audio_quality_benchmarks.rs | Removes audio quality benchmarks. |
| crates/coldvox-audio-quality/README.md | Removes audio quality crate README. |
| crates/coldvox-audio-quality/Cargo.toml | Removes audio quality crate manifest. |
| crates/app/tests/tui_dashboard_test.rs | Removes TUI dashboard “test as binary” workaround. |
| crates/app/tests/tui_dashboard_manual_test.rs | Removes manual binary integration test. |
| crates/app/tests/settings_test.rs | Removes remote-STT config tests and temp config helpers. |
| crates/app/tests/integration/text_injection_integration_test.rs | Removes test file-logging scaffolding. |
| crates/app/tests/integration/mock_injection_tests.rs | Removes test file-logging scaffolding. |
| crates/app/tests/integration/capture_integration_test.rs | Simplifies timeouts/logging and shutdown flow in capture tests. |
| crates/app/tests/hardware_check.rs | Removes hardware capability test suite. |
| crates/app/tests/common/timeout.rs | Increases default/extended test timeouts. |
| crates/app/tests/common/test_utils.rs | Removes crate-level dead-code allow attribute. |
| crates/app/tests/common/mod.rs | Removes shared logging module export. |
| crates/app/tests/common/logging.rs | Removes shared test logging module. |
| crates/app/src/tui.rs | Updates feature gates and adds transcription/plugin metrics fields. |
| crates/app/src/stt/tests/mod.rs | Changes STT tests to gate on whisper feature. |
| crates/app/src/stt/processor.rs | Changes processor gating to whisper; updates stub messaging. |
| crates/app/src/stt/mod.rs | Broadens module gating to whisper/parakeet. |
| crates/app/src/main.rs | Builds PluginSelectionConfig explicitly from settings (and removes remote config glue). |
| crates/app/src/bin/mic_probe.rs | Updates device naming API to cpal 0.16 name(). |
| crates/app/src/audio/test_rubato_api.rs | Removes rubato API probe file. |
| crates/app/config/plugins.json | Adds app-local plugin selection JSON. |
| crates/app/config/default.toml | Adds app-local injection defaults TOML. |
| crates/app/Cargo.toml | Removes explicit test/bin declarations and updates deps + feature list. |
| config/plugins.json | Updates canonical plugin selection defaults and policies. |
| config/default.toml | Updates injection latency defaults and STT config defaults. |
| WINDOWS_IMPLEMENTATION_SUMMARY.md | Removes outdated Windows implementation report. |
| VERIFICATION_REPORT.md | Removes outdated verification report. |
| README.md | Updates root README (hooks, quickstart, config notes, Python notes). |
| PR-190-Comprehensive-Assessment.md | Adds PR assessment document (new). |
| GEMINI.md | Removes duplicated agent instructions file. |
| FINAL_REPORT.md | Removes outdated final report. |
| DEPENDENCY_AUDIT_ISSUE.md | Removes dependency audit issue doc. |
| Cargo.toml | Removes audio-quality crate and switches GUI workspace member. |
| CHANGELOG.md | Removes prior unreleased Tauri/React notes; adds Qt transcript overlay notes. |
| AGENTS.md | Expands agent instructions and updates commands/features. |
| .sisyphus/ralph-loop.local.md | Removes local agent loop state file. |
| .pre-commit-config.yaml | Removes pre-commit config in favor of other tooling. |
| .kilocode/rules/agents.md | Changes to reference root AGENTS.md. |
| .github/workflows/vosk-integration.yml | Adds disabled “Whisper Integration Tests” workflow placeholder. |
| .github/workflows/docs-ci.yml | Switches docs CI to uv pip install -r requirements.txt and validate script. |
| .github/workflows/ci-minimal.yml | Adds a new minimal CI workflow with optional injection + whisper E2E. |
| .github/workflow-job-classifier.yml | Adds setup-vosk-model example job classification. |
| .github/copilot-instructions.md | Changes to reference root AGENTS.md. |
| .github/agents/tester.agent.md | Removes GH agent descriptor. |
| .github/agents/researcher.agent.md | Removes GH agent descriptor. |
| .github/agents/implementer.agent.md | Removes GH agent descriptor. |
| .github/actions/setup-coldvox/action.yml | Changes required commands list (adds Xvfb/openbox). |
| .githooks/pre-push | Removes hook script content. |
| .githooks/pre-commit | Removes hook script content. |
| .githooks/post-merge | Removes hook script content. |
| .githooks/post-checkout | Removes hook script content. |
| .gitattributes | Removes line-ending normalization config. |
| .envrc | Removes direnv setup for uv/venv. |
| .cargo/config.toml | Changes default PYO3_PYTHON path to .venv/bin/python. |
| window: &str, | ||
| ) -> InjectionResult<ConfirmationResult> { | ||
| let start_time = Instant::now(); | ||
| let _start_time = Instant::now(); |
| let status = Command::new(env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())) | ||
| .arg("build") | ||
| .arg("--manifest-path") | ||
| .arg("test-apps/terminal-test-app/Cargo.toml") | ||
| .arg("--package") | ||
| .arg("terminal-test-app") | ||
| .arg("--release") // Build in release mode for faster startup. | ||
| .arg("--locked") | ||
| .arg("--target-dir") | ||
| .arg(&target_dir) | ||
| .status() |
| MenuItem { text: (root.stateCode === 1) ? "Stop" : "Start"; onTriggered: { if (root.stateCode === 1) bridge.cmd_stop(); else bridge.cmd_start(); } } | ||
| MenuItem { text: "Pause/Resume"; onTriggered: bridge.cmd_toggle_pause() } | ||
| MenuItem { text: "Clear"; onTriggered: bridge.cmd_clear() } |
| { | ||
| "preferred_plugin": "mock", | ||
| "fallback_plugins": [ | ||
| "whisper", | ||
| "whisper-local", | ||
| "gcloud" | ||
| ], |
| # Ensure PyO3 uses the repo-local virtualenv Python, independent of shell activation. | ||
| # The relative path keeps this portable across machines. | ||
| PYO3_PYTHON = { value = "./.venv/Scripts/python.exe", relative = true } | ||
| PYO3_PYTHON = { value = "./.venv/bin/python", relative = true } |
| This project uses a "Zero-Latency" git hook standard powered by **[mise](https://mise.jdx.dev)** and **lint-staged**. | ||
|
|
||
| ## North Star | ||
| ### Setup | ||
| 1. **Install mise**: `curl https://mise.run | sh` (or see [docs](https://mise.jdx.dev/getting-started.html)) | ||
| 2. **Install dependencies**: `mise install` |
| Python::with_gil(|py| { | ||
| PyModule::import(py, "transformers").map_err(|_| { | ||
| SttError::LoadFailed( | ||
| "transformers not installed. Run: pip install transformers>=4.35.0".to_string(), |
| @@ -16,7 +16,6 @@ pub use chunker::{AudioChunker, AudioFrame, ChunkerConfig, ResamplerQuality}; | |||
| pub use device::{DeviceInfo, DeviceManager}; | |||
| pub use frame_reader::FrameReader; | |||
| pub use monitor::DeviceMonitor; | |||
| pub mod real_injection; | ||
| #[cfg(feature = "real-injection-tests")] | ||
| pub mod test_harness; | ||
| // pub mod real_injection; |
| self.metrics.record_end_to_end_latency(end_to_end_latency); | ||
| self.metrics | ||
| .record_engine_processing_time(engine_processing_time); |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 770f817de1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| preferred_plugin: Some("whisper".to_string()), | ||
| fallback_plugins: vec![], |
There was a problem hiding this comment.
Use available STT backend instead of hard-coding whisper
cmd_start forces preferred_plugin to "whisper" with no fallbacks, so the GUI startup path fails whenever Whisper is not compiled in (for example, this same commit wires coldvox-gui to coldvox-app with moonshine enabled). In those builds, pressing Start immediately drives the app into the error path instead of selecting an available backend.
Useful? React with 👍 / 👎.
| ControlButton { | ||
| label: st === 1 ? "⏸" : "▶" | ||
| onClicked: { | ||
| if (typeof bridge !== 'undefined' && bridge.cmd_toggle_pause) bridge.cmd_toggle_pause() |
There was a problem hiding this comment.
Call pause/resume invokables that exist on the bridge
The pause/resume button still invokes bridge.cmd_toggle_pause, but GuiBridge only exposes cmd_pause and cmd_resume. Because this is guarded by an existence check, the click path silently no-ops against the backend and only mutates local UI state, so transcription continues instead of actually pausing/resuming.
Useful? React with 👍 / 👎.
| onPositionChanged: root.doDrag(mouse) | ||
| onClicked: { | ||
| expanded = true | ||
| st = 1 // start recording state visually |
There was a problem hiding this comment.
Keep
st bound to bridge state instead of overwriting it
st is declared as a live binding to bridge.state, but assigning st = 1 in the click handler breaks that binding in QML. After the first click, st no longer tracks backend transitions (Active/Pause/Error), which makes status colors/icons and control branching depend on stale local state rather than the real pipeline state.
Useful? React with 👍 / 👎.
- Fix CRITICAL: replace non-existent bridge.cmd_toggle_pause() in AppRoot.qml and Main.qml with state-aware cmd_pause()/cmd_resume() - Fix CRITICAL: change coldvox-gui Cargo.toml dep from moonshine (which doesn't gate stt_rx) to parakeet feature - Fix HIGH: tray menu stateCode check was === 1 (Activating) not === 2 (Active) for Stop/Start label and trigger - Fix HIGH: gc_inactive_models() lacked active-plugin guard — could evict the running plugin; add snapshot-before-filter pattern - Fix MEDIUM: double stt_gc_runs metrics increment in gc_inactive_models - Fix MEDIUM: processor.rs and tui_dashboard.rs feature gates were whisper-only; broaden to any(whisper, parakeet) - Fix LOW: leading newline on first final transcript line in bridge.rs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
GuiBridgenow receivesTranscriptionEvent::{Partial,Final}and setspartial_transcript/final_transcriptproperties viaCxxQtThread::queuebridge.level,bridge.transcript,bridge.toggle_expand(),bridge.cmd_toggle_pause(),bridge.demo_set_level(),bridge.demo_append_delta()calls; replaced with correct bridge APIAppRoot.qmlexpanded toggle — replacedbridge.toggle_expand()invokable calls with direct property writebridge.expanded = !bridge.expandedbridge.stateand callsbridge.cmd_pause()orbridge.cmd_resume()accordinglySettingsWindow.qml— added missingopacityValueproperty so theConnectionshandler inAppRootno longer failsMain.qmlstate binding —property int stnow reflects livebridge.stateviatypeofguard;scrollToBottom()is called on transcriptonTextChangedbridge.rserror path —cmd_starterror branch now queues a state update toAppState::Errorinstead of leaving state stuck inActivating/Active#[cfg(feature = "whisper")]gates inruntime.rs,tui.rs,stt/mod.rsbroadened toany(feature = "whisper", feature = "parakeet")so parakeet builds compile correctlyzbusunconditional dependency — moved from[dependencies]to[target.'cfg(target_os = "linux")'.dependencies]to fix Windows/macOS buildsSttPluginManagerconfig load — removedlet _ = manager.load_config()from constructor (dropped Future, never loaded); caller nowawaitsload_config()explicitlyClearfallback that overwrote bridge property bindingsTest plan
cargo checkpasses with no new errors (verified locally)cargo check --features parakeetcompiles withoutwhisper-gate exclusionscargo check --target x86_64-pc-windows-msvcpasses (zbus no longer in unconditional deps)final_transcriptandpartial_transcriptcorrectlybridge.statebridge.expandedopacityValuepropertySttPluginManagerloads plugin config on startup without silent no-op🤖 Generated with Claude Code