Skip to content

test(windows): 增加真机回归 smoke 矩阵#73

Merged
appergb merged 1 commit into
Open-Less:mainfrom
Cooper-X-Oak:codex/windows-real-regression-suite-pr
Apr 30, 2026
Merged

test(windows): 增加真机回归 smoke 矩阵#73
appergb merged 1 commit into
Open-Less:mainfrom
Cooper-X-Oak:codex/windows-real-regression-suite-pr

Conversation

@Cooper-X-Oak
Copy link
Copy Markdown
Contributor

@Cooper-X-Oak Cooper-X-Oak commented Apr 30, 2026

摘要

Fixes #无(不再新增 upstream issue)。

关联 fork 验证:Cooper-X-Oak#12

本 PR 是从 fork/dev 已验证批次拆出的 Windows 真机回归维护项:把物理热键/合成热键、真实 ASR、Notepad 与浏览器输入框插入 fallback、麦克风隐私关闭/恢复等场景沉淀为可复跑的 PowerShell smoke 脚本。

修复 / 新增 / 改进

  • 新增 windows-hotkey-injection-smoke.ps1:无物理键触发 coordinator 热键链路。
  • 新增 windows-real-asr-insertion-smoke.ps1:真实 ASR 后验证 Notepad / 浏览器输入框插入和 history 写入。
  • 新增 windows-microphone-privacy-smoke.ps1:覆盖 Windows 麦克风隐私拒绝 / 恢复路径。
  • 新增 windows-real-regression.ps1:检查真实凭据、本地偏好和回归入口。
  • 新增 windows-smoke-suite.ps1:串联 runtime、hotkey、ASR 插入和隐私 smoke。

兼容

测试计划

  • 命令:git diff --check -- openless-all/app/scripts
  • 结果:通过。
  • 命令:PowerShell Parser 逐个解析 5 个新增脚本。
  • 结果:全部通过。
  • 命令:检查本批脚本未包含用户真实密钥。
  • 结果:未命中。
  • 证据路径:真实 ASR / 麦克风隐私 / 前台应用插入 smoke 需要 Windows 真机显式执行。

Summary by Sourcery

Add Windows real-device regression smoke scripts for hotkey handling, real ASR insertion, microphone privacy, and a composed smoke suite.

New Features:

  • Introduce a PowerShell smoke script to verify coordinator hotkey handling via injected debug events without physical keyboard input.
  • Add a PowerShell smoke script to validate real ASR dictation, history updates, and insertion fallback into Notepad and browser inputs on Windows.
  • Add a PowerShell smoke script to exercise Windows microphone privacy deny/restore behavior and corresponding OpenLess logging.
  • Add a Windows real regression helper script to check credential presence, runtime startup, hotkey listener, and optional manual gates for hotkey, insertion fallback, and microphone privacy.
  • Add an orchestrating Windows smoke suite script that parses, optionally builds, and runs the individual runtime, hotkey, ASR, and privacy smoke checks.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 30, 2026

Reviewer's Guide

Adds a Windows real-device regression smoke matrix implemented as PowerShell scripts that exercise runtime startup, hotkey injection, real ASR insertion into Notepad/browser with fallback, microphone privacy registry gates, and a top-level suite/orchestrator for these checks.

Sequence diagram for real ASR insertion fallback smoke script

sequenceDiagram
  participant RealAsrScript as windows_real_asr_insertion_smoke_ps1
  participant OpenLess as openless_exe
  participant WinHook as WH_KEYBOARD_LL
  participant InputApp as Notepad_or_Browser
  participant Speech as System_Speech_Synthesizer
  participant History as history_json
  participant Log as openless_log
  participant Clipboard as Clipboard

  RealAsrScript->>RealAsrScript: Get_OpenLessCredentialStatus
  RealAsrScript->>RealAsrScript: Set_HoldHotkeyPreference
  RealAsrScript->>OpenLess: Start_Process with env flags
  OpenLess->>WinHook: install low_level_keyboard_hook
  WinHook-->>Log: write WH_KEYBOARD_LL installed
  RealAsrScript->>Log: Wait_LogPattern WH_KEYBOARD_LL installed

  RealAsrScript->>InputApp: Start_InputTarget(Target)
  RealAsrScript->>WinHook: Press_Hotkey (synthetic keybd_event)
  WinHook-->>Log: write [hotkey] Windows trigger pressed
  RealAsrScript->>Log: Wait_LogPattern [hotkey] Windows trigger pressed

  OpenLess->>Log: write [coord] session started
  RealAsrScript->>Log: Wait_LogPattern [coord] session started

  RealAsrScript->>Speech: Speak_TestPhrase(Phrase)
  Speech-->>OpenLess: audio via microphone route

  RealAsrScript->>WinHook: Release_Hotkey
  OpenLess->>History: append new dictation entry
  RealAsrScript->>History: Wait_HistoryCountGreaterThan(baseline)
  RealAsrScript->>History: Get_LatestHistory

  RealAsrScript->>RealAsrScript: Assert rawTranscript, finalText, insertStatus=copiedFallback

  RealAsrScript->>InputApp: Focus_Window
  RealAsrScript->>InputApp: Send_CtrlChord(A) then C
  InputApp->>Clipboard: set text from editable area
  RealAsrScript->>Clipboard: Get_Clipboard
  RealAsrScript->>RealAsrScript: Assert clipboard text non_empty

  RealAsrScript->>OpenLess: Stop_Process
  RealAsrScript->>RealAsrScript: Restore previous preferences_json
Loading

Sequence diagram for Windows microphone privacy smoke script

sequenceDiagram
  participant MicScript as windows_microphone_privacy_smoke_ps1
  participant Registry as CapabilityAccessManager_registry
  participant OpenLess as openless_exe
  participant WinHook as WH_KEYBOARD_LL
  participant Log as openless_log
  participant Notepad as notepad_exe

  MicScript->>Registry: Get_ConsentSnapshot(global, desktop, app)
  MicScript->>MicScript: Set_HoldHotkeyPreference

  MicScript->>Registry: Set global, desktop, app Value=Deny

  loop privacy_denied_attempt
    MicScript->>OpenLess: Start_Process with ACCEPT_SYNTHETIC_HOTKEY
    OpenLess->>WinHook: install low_level_keyboard_hook
    WinHook-->>Log: write WH_KEYBOARD_LL installed
    MicScript->>Log: Wait_LogPattern WH_KEYBOARD_LL installed

    MicScript->>Notepad: Start_Process and focus
    MicScript->>WinHook: Press_Hotkey (synthetic)
    WinHook-->>Log: write [hotkey] Windows trigger pressed
    MicScript->>WinHook: Release_Hotkey

    OpenLess-->>Log: write microphone permission gate failed or input probe failed
    MicScript->>Log: Wait_LogPattern ExpectedPattern and assert no session_started
    MicScript->>OpenLess: Stop_Process
  end

  MicScript->>Registry: Set global, desktop, app Value=Allow

  loop privacy_restored_attempt
    MicScript->>OpenLess: Start_Process with ACCEPT_SYNTHETIC_HOTKEY
    OpenLess->>WinHook: install low_level_keyboard_hook
    WinHook-->>Log: write WH_KEYBOARD_LL installed
    MicScript->>Log: Wait_LogPattern WH_KEYBOARD_LL installed

    MicScript->>Notepad: Start_Process and focus
    MicScript->>WinHook: Press_Hotkey (synthetic)
    WinHook-->>Log: write [hotkey] Windows trigger pressed
    MicScript->>WinHook: Release_Hotkey

    OpenLess-->>Log: write [coord] session started
    MicScript->>Log: Wait_LogPattern [coord] session started and assert no permission_gate_failure
    MicScript->>OpenLess: Stop_Process
  end

  MicScript->>Registry: Restore_ConsentSnapshot for global, desktop, app
  MicScript->>MicScript: Restore preferences_json
Loading

Sequence diagram for hotkey injection smoke without physical keyboard

sequenceDiagram
  participant InjectScript as windows_hotkey_injection_smoke_ps1
  participant OpenLess as openless_exe
  participant WinHook as WH_KEYBOARD_LL
  participant Log as openless_log

  InjectScript->>InjectScript: Resolve ExePath
  InjectScript->>InjectScript: Kill existing openless, delete log

  InjectScript->>OpenLess: Start_Process with OPENLESS_DEBUG_HOTKEY_ON_START=1
  OpenLess->>WinHook: install low_level_keyboard_hook
  OpenLess-->>Log: write [debug] injecting startup hotkey press
  OpenLess-->>Log: write [coord] hotkey pressed

  InjectScript->>Log: Wait_LogPattern [debug] injecting startup hotkey press
  InjectScript->>Log: Wait_LogPattern [coord] hotkey pressed
  InjectScript->>OpenLess: Stop_Process
Loading

Flow diagram for windows smoke suite orchestrator

flowchart TD
  Start([Start windows_smoke_suite_ps1])
  Init["Resolve appRoot and ExePath
Ensure SystemDrive and ProgramData"]
  ParseStep["Invoke-Step PowerShell syntax
Parse windows-*.ps1 scripts"]
  BuildCheck{Build switch?}
  BuildStep["Invoke-Step Windows GNU build
Call windows-build-gnu.ps1"]
  CheckExe{ExePath exists?}
  RuntimeCheck{SkipRuntime switch?}
  RuntimeStep["Invoke-Step Runtime smoke
windows-runtime-smoke.ps1 -RequireCredentials"]
  HotkeyCheck{SkipHotkey switch?}
  HotkeyStep["Invoke-Step OS hotkey smoke
windows-hotkey-os-hook-smoke.ps1"]
  RealAsrCheck{SkipRealAsr switch?}
  ForEachTarget[[For each Target in Targets]]
  RealAsrStep["Invoke-Step Real ASR insertion fallback
windows-real-asr-insertion-smoke.ps1
with ExePath, Target, Phrase, DebugHotkeyEvents"]
  PrivacyCheck{SkipPrivacy switch?}
  PrivacyStep["Invoke-Step Microphone privacy deny/restore
windows-microphone-privacy-smoke.ps1"]
  StopOpenLess["Stop all openless processes"]
  End([Windows smoke suite passed])

  Start --> Init --> ParseStep --> BuildCheck
  BuildCheck -- yes --> BuildStep --> CheckExe
  BuildCheck -- no --> CheckExe
  CheckExe -- no --> ErrExe[[Error: openless.exe not found]]
  CheckExe -- yes --> RuntimeCheck

  RuntimeCheck -- no_skip --> RuntimeStep --> HotkeyCheck
  RuntimeCheck -- skip --> HotkeyCheck

  HotkeyCheck -- no_skip --> HotkeyStep --> RealAsrCheck
  HotkeyCheck -- skip --> RealAsrCheck

  RealAsrCheck -- no_skip --> ForEachTarget --> RealAsrStep --> PrivacyCheck
  RealAsrCheck -- skip --> PrivacyCheck

  PrivacyCheck -- no_skip --> PrivacyStep --> StopOpenLess --> End
  PrivacyCheck -- skip --> StopOpenLess --> End
Loading

File-Level Changes

Change Details Files
Introduce a real ASR + insertion fallback smoke script that drives OpenLess end-to-end using speech synthesis and validates history + clipboard behavior in Notepad and browser fixtures.
  • Locate or default the OpenLess Windows GNU dev executable and ensure required environment variables such as SystemDrive/ProgramData are set.
  • Embed minimal Win32 interop to focus windows and synthesize keyboard events (hotkey press/release, Ctrl chords).
  • Add helpers to read/write UTF-8 JSON preferences and history, enforce a hold-mode right-control hotkey, and restore previous preferences after the run.
  • Implement browser input fixtures using a temporary HTML textarea page with a dedicated user-data-dir profile, plus cleanup of processes and temp files.
  • Check for configured Volcengine ASR and Ark LLM credentials, then launch OpenLess with synthetic hotkey acceptance, wait for keyboard hook installation, and drive a full session via speech synthesis.
  • Validate that history grows, the latest entry has non-empty transcripts, insertStatus is copiedFallback, and verify target text via clipboard readback from Notepad/browser.
openless-all/app/scripts/windows-real-asr-insertion-smoke.ps1
Add a microphone privacy smoke script that flips Windows CapabilityAccessManager microphone consent state and validates OpenLess behavior in denied vs allowed modes.
  • Embed Win32 interop for keyboard events and window focus, plus shared helpers to parse/write UTF-8 preferences and enforce a hold-mode right-control hotkey.
  • Implement registry snapshot/restore helpers for global, desktop (NonPackaged), and app-specific microphone consent keys to avoid persistent environment mutation.
  • Provide helpers to compute the NonPackaged consent path for the OpenLess executable and to set consent Value entries to Allow/Deny.
  • Implement an Invoke-HotkeyAttempt routine that launches OpenLess with synthetic hotkey acceptance, drives a notepad-focused hotkey press, and asserts on expected/forbidden log patterns.
  • Run two passes: one with all relevant microphone consent keys set to Deny (expect permission gate failure and no session start) and one with them set to Allow (expect session start, no gate failure), then restore consent snapshots and preferences.
openless-all/app/scripts/windows-microphone-privacy-smoke.ps1
Add a real regression entry-point script that checks credentials, verifies basic runtime startup, and optionally gates physical hotkey, insertion fallback, and microphone privacy flows.
  • Resolve OpenLess executable path, set baseline environment variables, and compute log/history paths.
  • Implement credential inspection for Volcengine ASR and Ark LLM from credentials.json with an optional RequireCredentials gate that fails if either provider is missing.
  • Add helpers to poll logs for patterns and to detect history.json write-time changes to confirm manual recording activity.
  • Launch OpenLess, verify the process stays alive and responsive, and assert that the hotkey listener installs within a configurable startup timeout.
  • Add optional PhysicalHotkey gate that requires a physical hotkey press to be observed in logs, an InsertionFallback gate that waits for manual recording to update history (with a Notepad helper), and a MicrophonePrivacy gate that opens the Windows microphone privacy settings for manual verification before shutting down OpenLess.
  • Ensure OpenLess processes are stopped on completion or failure.
openless-all/app/scripts/windows-real-regression.ps1
Introduce a top-level Windows smoke suite orchestrator that validates script syntax, optionally builds the Windows GNU binary, and chains runtime, hotkey, real ASR insertion, and microphone privacy smokes.
  • Resolve app root and default ExePath, set baseline environment variables, and define a generic Invoke-Step wrapper that times and logs each sub-step with ok/fail status.
  • Implement a Test-PowerShellSyntax helper using the PowerShell parser to pre-parse a fixed set of smoke scripts before running them.
  • Add an Invoke-Script helper to run sibling scripts with parameter passthrough.
  • Optionally trigger the Windows GNU build script before running tests when -Build is specified and fail early if the executable is missing.
  • Conditionally invoke runtime, OS hotkey, real ASR insertion (per-target loop with optional hotkey debug), and microphone privacy smoke scripts, with Skip* switches to selectively disable stages.
  • Ensure any lingering openless processes are killed at the end, and print a final suite-passed message.
openless-all/app/scripts/windows-smoke-suite.ps1
Add a hotkey injection smoke script that validates the OpenLess debug startup hotkey injection path without requiring physical key presses.
  • Resolve OpenLess executable path with a default to the Windows GNU dev artifact and ensure required env variables are set.
  • Implement tail-based log polling for specific patterns within a timeout window.
  • Kill existing openless processes and clear the log file, then start OpenLess with OPENLESS_DEBUG_HOTKEY_ON_START set.
  • Assert that the log first records the injected startup hotkey press and then the coordinator observing the hotkey, within the timeout, and tear down the process and environment variable.
  • Emit success/failure messages for the coordinator hotkey path with no physical keyboard input.
openless-all/app/scripts/windows-hotkey-injection-smoke.ps1

Possibly linked issues

  • #: PR adds the exact Windows real regression scripts, credential gate, and flows requested by the issue.
  • #[windows] 热键链路缺少非人工自动注入门禁: PR’s windows-hotkey-injection-smoke.ps1 implements the requested non-physical hotkey injection gate and log assertion.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • Several helper functions like Set-HoldHotkeyPreference, Read-TextUtf8, and Wait-LogPattern are duplicated across scripts; consider extracting them into a shared helper module to reduce repetition and keep behavior consistent.
  • In windows-hotkey-injection-smoke.ps1, the Wait-LogPattern function takes a $Since argument that is never used; either incorporate it into the filtering logic or remove the parameter to avoid confusion.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several helper functions like `Set-HoldHotkeyPreference`, `Read-TextUtf8`, and `Wait-LogPattern` are duplicated across scripts; consider extracting them into a shared helper module to reduce repetition and keep behavior consistent.
- In `windows-hotkey-injection-smoke.ps1`, the `Wait-LogPattern` function takes a `$Since` argument that is never used; either incorporate it into the filtering logic or remove the parameter to avoid confusion.

## Individual Comments

### Comment 1
<location path="openless-all/app/scripts/windows-hotkey-injection-smoke.ps1" line_range="20-29" />
<code_context>
+  $env:ProgramData = Join-Path $env:SystemDrive "ProgramData"
+}
+
+function Wait-LogPattern($Path, $Pattern, $Since, $TimeoutSeconds) {
+  $deadline = (Get-Date).AddSeconds($TimeoutSeconds)
+  while ((Get-Date) -lt $deadline) {
+    if (Test-Path $Path) {
+      $lines = Get-Content -Path $Path -Tail 200
+      foreach ($line in $lines) {
+        if ($line -match $Pattern) {
+          return $true
+        }
+      }
+    }
+    Start-Sleep -Milliseconds 500
+  }
+  return $false
+}
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The `$Since` parameter is unused in `Wait-LogPattern`, which can be misleading and suggests incomplete filtering logic.

Since `$Since` is never read and the function always tails the last 200 lines, callers can’t rely on it to avoid matching older log entries. Consider either removing `$Since` from the signature or implementing actual since-based filtering (e.g., by tracking timestamps or line offsets).
</issue_to_address>

### Comment 2
<location path="openless-all/app/scripts/windows-microphone-privacy-smoke.ps1" line_range="164-173" />
<code_context>
+  }
+}
+
+function Restore-ConsentSnapshot($Snapshot) {
+  if (-not $Snapshot.Exists) {
+    Remove-Item -LiteralPath $Snapshot.Path -Recurse -Force -ErrorAction SilentlyContinue
+    return
+  }
+  if (-not (Test-Path $Snapshot.Path)) {
+    New-Item -ItemType Directory -Path $Snapshot.Path | Out-Null
+  }
+  if ($Snapshot.ValueExists) {
+    Set-ItemProperty -LiteralPath $Snapshot.Path -Name Value -Value $Snapshot.Value
+  } else {
+    Remove-ItemProperty -LiteralPath $Snapshot.Path -Name Value -ErrorAction SilentlyContinue
</code_context>
<issue_to_address>
**suggestion:** Registry restoration uses `New-Item -ItemType Directory` on HKCU paths, which works but is semantically off for registry keys.

In the registry provider this happens to create a key, but it’s misleading and relies on provider-specific behavior. Prefer `New-Item -ItemType Key -Force` (or omit `-ItemType` and let the registry provider infer it) so the intent is clear and behavior is more robust across environments and PowerShell versions.

Suggested implementation:

```
  if (-not (Test-Path $Snapshot.Path)) {
    New-Item -ItemType Key -Path $Snapshot.Path -Force | Out-Null
  }

```

```
  if (-not (Test-Path $Path)) {
    New-Item -ItemType Key -Path $Path -Force | Out-Null
  }

```
</issue_to_address>

### Comment 3
<location path="openless-all/app/scripts/windows-real-regression.ps1" line_range="25-16" />
<code_context>
+}
+"@
+
+function Test-CredentialValue($Value) {
+  return ($null -ne $Value) -and ($Value -is [string]) -and ($Value.Trim().Length -gt 0)
+}
+
+function Get-OpenLessCredentialStatus {
</code_context>
<issue_to_address>
**suggestion:** Credential parsing and validation logic is duplicated across scripts and could be centralized.

`windows-real-regression.ps1` and `windows-real-asr-insertion-smoke.ps1` both define nearly identical `Test-CredentialValue` and `Get-OpenLessCredentialStatus` helpers. Please extract these into a shared script (e.g., dot-sourced by each entrypoint) to keep credential validation consistent as the schema or rules evolve.

Suggested implementation:

```
if (-not $env:SystemDrive) {
  $env:SystemDrive = "C:"
}
if (-not $env:ProgramData) {
  $env:ProgramData = Join-Path $env:SystemDrive "ProgramData"
}

# Load shared credential helpers (Test-CredentialValue, Get-OpenLessCredentialStatus, etc.)
. (Join-Path $PSScriptRoot "windows-credentials.ps1")


```

To fully implement the refactoring and remove duplication:

1. **Create a shared helper script** `openless-all/app/scripts/windows-credentials.ps1` with the common implementations (based on current logic), for example:

   ```powershell
   function Test-CredentialValue {
     param(
       [Parameter(Mandatory = $true)]
       [object]$Value
     )

     return ($null -ne $Value) -and ($Value -is [string]) -and ($Value.Trim().Length -gt 0)
   }

   function Get-OpenLessCredentialStatus {
     $path = Join-Path $env:APPDATA "OpenLess\credentials.json"
     if (-not (Test-Path $path)) {
       return [pscustomobject]@{
         Path               = $path
         Present            = $false
         VolcengineConfigured = $false
         ArkConfigured      = $false
       }
     }

     # ...existing body of Get-OpenLessCredentialStatus from one of the scripts...
   }
   ```

2. **In `openless-all/app/scripts/windows-real-regression.ps1`**, remove the now-duplicated implementations of `Test-CredentialValue` and `Get-OpenLessCredentialStatus` entirely (the edit block above replaces the top of that section; you should remove any remaining parts of these function bodies below the shown snippet if present).

3. **In `openless-all/app/scripts/windows-real-asr-insertion-smoke.ps1`**, add the same dot-sourcing line:

   ```powershell
   . (Join-Path $PSScriptRoot "windows-credentials.ps1")
   ```

   and remove its local definitions of `Test-CredentialValue` and `Get-OpenLessCredentialStatus`.

4. Ensure any future credential-related helpers are added only to `windows-credentials.ps1` and consumed via dot-sourcing, keeping schema/rule changes centralized.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +20 to +29
function Wait-LogPattern($Path, $Pattern, $Since, $TimeoutSeconds) {
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ((Get-Date) -lt $deadline) {
if (Test-Path $Path) {
$lines = Get-Content -Path $Path -Tail 200
foreach ($line in $lines) {
if ($line -match $Pattern) {
return $true
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The $Since parameter is unused in Wait-LogPattern, which can be misleading and suggests incomplete filtering logic.

Since $Since is never read and the function always tails the last 200 lines, callers can’t rely on it to avoid matching older log entries. Consider either removing $Since from the signature or implementing actual since-based filtering (e.g., by tracking timestamps or line offsets).

Comment on lines +164 to +173
function Restore-ConsentSnapshot($Snapshot) {
if (-not $Snapshot.Exists) {
Remove-Item -LiteralPath $Snapshot.Path -Recurse -Force -ErrorAction SilentlyContinue
return
}
if (-not (Test-Path $Snapshot.Path)) {
New-Item -ItemType Directory -Path $Snapshot.Path | Out-Null
}
if ($Snapshot.ValueExists) {
Set-ItemProperty -LiteralPath $Snapshot.Path -Name Value -Value $Snapshot.Value
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Registry restoration uses New-Item -ItemType Directory on HKCU paths, which works but is semantically off for registry keys.

In the registry provider this happens to create a key, but it’s misleading and relies on provider-specific behavior. Prefer New-Item -ItemType Key -Force (or omit -ItemType and let the registry provider infer it) so the intent is clear and behavior is more robust across environments and PowerShell versions.

Suggested implementation:

  if (-not (Test-Path $Snapshot.Path)) {
    New-Item -ItemType Key -Path $Snapshot.Path -Force | Out-Null
  }

  if (-not (Test-Path $Path)) {
    New-Item -ItemType Key -Path $Path -Force | Out-Null
  }

if ([string]::IsNullOrWhiteSpace($ExePath)) {
$appRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
$ExePath = Join-Path $appRoot ".artifacts\windows-gnu\dev\openless.exe"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Credential parsing and validation logic is duplicated across scripts and could be centralized.

windows-real-regression.ps1 and windows-real-asr-insertion-smoke.ps1 both define nearly identical Test-CredentialValue and Get-OpenLessCredentialStatus helpers. Please extract these into a shared script (e.g., dot-sourced by each entrypoint) to keep credential validation consistent as the schema or rules evolve.

Suggested implementation:

if (-not $env:SystemDrive) {
  $env:SystemDrive = "C:"
}
if (-not $env:ProgramData) {
  $env:ProgramData = Join-Path $env:SystemDrive "ProgramData"
}

# Load shared credential helpers (Test-CredentialValue, Get-OpenLessCredentialStatus, etc.)
. (Join-Path $PSScriptRoot "windows-credentials.ps1")


To fully implement the refactoring and remove duplication:

  1. Create a shared helper script openless-all/app/scripts/windows-credentials.ps1 with the common implementations (based on current logic), for example:

    function Test-CredentialValue {
      param(
        [Parameter(Mandatory = $true)]
        [object]$Value
      )
    
      return ($null -ne $Value) -and ($Value -is [string]) -and ($Value.Trim().Length -gt 0)
    }
    
    function Get-OpenLessCredentialStatus {
      $path = Join-Path $env:APPDATA "OpenLess\credentials.json"
      if (-not (Test-Path $path)) {
        return [pscustomobject]@{
          Path               = $path
          Present            = $false
          VolcengineConfigured = $false
          ArkConfigured      = $false
        }
      }
    
      # ...existing body of Get-OpenLessCredentialStatus from one of the scripts...
    }
  2. In openless-all/app/scripts/windows-real-regression.ps1, remove the now-duplicated implementations of Test-CredentialValue and Get-OpenLessCredentialStatus entirely (the edit block above replaces the top of that section; you should remove any remaining parts of these function bodies below the shown snippet if present).

  3. In openless-all/app/scripts/windows-real-asr-insertion-smoke.ps1, add the same dot-sourcing line:

    . (Join-Path $PSScriptRoot "windows-credentials.ps1")

    and remove its local definitions of Test-CredentialValue and Get-OpenLessCredentialStatus.

  4. Ensure any future credential-related helpers are added only to windows-credentials.ps1 and consumed via dot-sourcing, keeping schema/rule changes centralized.

@appergb appergb merged commit 96ff66e into Open-Less:main Apr 30, 2026
2 checks passed
appergb pushed a commit that referenced this pull request Apr 30, 2026
包含本轮所有合并:
- Codex 终审两条 HIGH (cancel race) 修复 (PR #79)
- 6 个 Cooper-X-Oak/Codex bot PRs 自动合并 (#44 #49 #53 #68 #72 #73)
- 2 个有冲突 PR 本地 rebase 后合并 (#66 cancel + 空转写并存 / #67 Windows docs)
- README 破图修复 (PR #80)
- workflow-scope 受限的 #48 + #75 由用户在 GitHub UI 直接合并

3 处版本字段同步:package.json + tauri.conf.json + Cargo.toml
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