Commit Graph
2 Commits
Author SHA1 Message Date
Palash Debnath 93025d9a81 fix(dictation): stop the widget stranding an empty square, repair the swept data dirs (#1398)
The dictation hotkey could leave a blank dark square stuck on the desktop with no way to dismiss it. Three defects compounded: the tray listener's effect depended on [state], so it detached across an await on every state change and a press landing in that gap was lost; an idle pill renders null, so the window Rust had already shown was empty; and the opaque chrome background made that empty window a hard-edged square. Nothing could hide it — dismiss() is only reachable from the X button, Esc, or a post-session timer, none of which exist for a session that never started.

Fixed at the invariant rather than the call sites: the listener subscribes once for the component's lifetime, the widget window's chrome background is transparent, and an idle-but-visible window reconciles itself to hidden. The reconcile is polled (a dropped press changes no React state, so there is nothing to key an effect off) and aborts if its effect is torn down mid-check, so it can never hide a dictation that has just started.

Also in scope:

- The rename sweep had repointed three data-dir literals at a brand-named directory that does not exist, so smoke-test.sh verified a directory the backend never writes and desktop-prod.sh silently stopped clearing backend state on Windows. Both invisible on macOS, where they are usually run. A guard test now pins the assignments specifically.
- The dictation model picker's download sizes were wrong for all seven models, in both directions — Parakeet TDT v3 (the recommended default) understated 180 MB against an actual 670 MB, while the low-RAM fallbacks were overstated threefold, discouraging exactly the choice that would have helped. Measured from the published repos and pinned by a test.
- The 0.6B Parakeet models now decode on more threads, capped by host cores and still overridable.
- uninstall.ps1 gained a UTF-8 BOM (Windows PowerShell 5.1 mis-decodes its non-ASCII output without one), and sponsor.yml lost its last OmniVoice references.
2026-08-07 05:39:41 +05:30
Palash DebnathandClaude Opus 4.8 24a00bea64 test(probe): spec-driven AI-agent test harness (L1–L5 + HTML report + triage) (#245)
* test(probe): add spec-driven AI-agent test harness (L1/L2/L4/L5 + report + triage)

Introduces `tests/probe/`, a portable, mostly-deterministic test harness built
on the Actor/Judge split: AI agents may drive and self-heal, but verdicts are
always deterministic code + metrics — no LLM on the verdict path.

Layers:
- L1 API: Schemathesis property-fuzz over in-process ASGI (enable-on-demand).
- L2 web: Playwright Driver + deterministic self-heal (id→test-id→text, loosened
  CSS) → pluggable Healer; LLMHealer/anthropic_healer for genuine agentic heal.
  Judges + self-heal logic unit-tested offline via FakePage; live browser skips.
- L4 media: audio correctness — exists/decode/duration/not-silent/clipping/NaN,
  round-trip ASR WER (pure-python, faster-whisper backend), speaker similarity.
  No golden-WAV (device-stable metrics only); naturalness is advisory-only.
- L5 env/first-run: fresh-data-dir backend boot in a SUBPROCESS (no session
  contamination), asserts health + DB init + endpoint reachability. Docker gated.

Plus: hybrid YAML spec engine + JudgeResult/registry; self-contained HTML report
that auto-opens (suppressed in CI/headless/PROBE_NO_OPEN); Triager that clusters
failures and drafts a prefilled GitHub issue URL (sanitized, no auto-submit) with
a one-click button in the report.

Dependency-light: runs in the base venv; schemathesis/resemblyzer/playwright/
anthropic are enable-on-demand and skip cleanly. Generated reports gitignored.
Full suite green (657 passed); no contamination of existing tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test(probe): add L3 desktop layer (Tauri config-integrity + guarded launch)

Per the architecture decision, desktop E2E is substituted by backend-over-HTTP
(L5) + browser (L2) since Tauri has no official macOS WebDriver. L3 guards the
packaging/shell contract a browser test can't see, against the real
tauri.conf.json (with platform-override merge), running on any platform with no
Tauri toolchain:

- version parity between tauri.conf.json and pyproject (release integrity)
- dev/build wiring (devUrl matches the Vite frontend, frontendDist, before* cmds)
- bundled binaries first-run depends on (uv / ffmpeg / ffprobe in externalBin)
- CSP actually permits the local backend origins (desktop-only failure mode:
  packaged app can't reach :3900 while the browser build works)

Adds desktop.py (config load + platform deep-merge + bundle discovery + launch
guard), judges/desktop.py (config_present/config_eq/config_contains/csp_allows),
desktop_smoke.probe.yaml, and tests covering integrity, platform-merge replace
semantics, and a live bundle launch that skips without a built bundle/display.

Full suite green (662 passed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 12:00:19 +05:30