Skip to content

[codex] Harden Windows file indexing and UserAssist parsing#7896

Open
tianmind-studio wants to merge 3 commits into
BasedHardware:mainfrom
tianmind-studio:codex/windows-index-usage-edge-cases
Open

[codex] Harden Windows file indexing and UserAssist parsing#7896
tianmind-studio wants to merge 3 commits into
BasedHardware:mainfrom
tianmind-studio:codex/windows-index-usage-edge-cases

Conversation

@tianmind-studio

@tianmind-studio tianmind-studio commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Skip file-index noise directories case-insensitively so Windows paths like .GIT, Node_Modules, or __PYCACHE__ do not get scanned.
  • Keep the exported SKIP_DIRS entries verbatim while using an internal normalized set for case-insensitive matching.
  • Parse UserAssist run/focus counters as unsigned DWORD values so long-lived Windows usage history cannot wrap into negative focus time.
  • Add focused unit coverage for both Windows edge cases.
  • Format the touched UserAssist edge-case test with the current Windows app dev dependencies.

Why

Windows directory matching is case-insensitive in practice, but the scan skip list was case-sensitive. UserAssist binary fields are DWORD counters; reading them as signed integers can make high-bit values negative, which would corrupt seeded usage ranking for long-lived installs.

Refresh

  • Rebased on main at 1a5824403b.
  • Current head: 86dfe2e724.
  • The Greptile concern about exporting pre-normalized SKIP_DIRS is already addressed; the review thread is resolved/outdated.

Validation

  • vitest run src/main/fileIndex/scanRules.test.ts src/main/usage/userAssist.test.ts -> 2 files passed, 22 tests passed
  • npm run typecheck -> passed
  • prettier --check src/main/fileIndex/scanRules.ts src/main/fileIndex/scanRules.test.ts src/main/usage/userAssist.ts src/main/usage/userAssist.test.ts -> passed
  • git diff --check origin/main...HEAD
  • scripts/pre-commit with the backend Windows venv and local Dart SDK on PATH

@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens two Windows-specific parsing paths: file-index directory skipping is made case-insensitive (fixing missed skips for paths like Node_Modules or .GIT), and UserAssist registry DWORD fields are read as unsigned integers instead of signed, preventing negative focus-time values on long-lived installs. Both fixes are accompanied by focused unit tests.

  • scanRules.ts: shouldVisitDir now calls .toLowerCase() before the SKIP_DIRS set lookup; set entries are normalized to lowercase accordingly.
  • userAssist.ts: readInt32LEreadUInt32LE for runCount, focusCount, and focusMs, correctly reflecting the Windows DWORD type (values up to ~4.3 billion no longer wrap negative).
  • Test helpers in userAssist.test.ts are updated to use writeUInt32LE, and new cases exercise values above INT32_MAX to directly prove the fix.

Confidence Score: 4/5

Both changes are narrow, well-targeted fixes with matching unit tests; the only thing to double-check is the exported SKIP_DIRS constant whose entries are now pre-lowercased.

The unsigned-read change in userAssist.ts is straightforward and the new test directly exercises values that would have produced negatives before. The case-insensitive directory skipping works correctly for all callers of shouldVisitDir. The sole concern is that the exported SKIP_DIRS constant silently changed its entry casing — any future direct consumer calling .has(name) without normalising first would get wrong results, but no such consumer exists today.

scanRules.ts — the exported SKIP_DIRS constant now holds pre-lowercased strings, which is invisible from the type signature.

Important Files Changed

Filename Overview
desktop/windows/src/main/fileIndex/scanRules.ts Added .toLowerCase() to shouldVisitDir for case-insensitive matching and normalised SKIP_DIRS entries to lowercase; exported constant now silently requires pre-normalised lookups.
desktop/windows/src/main/usage/userAssist.ts Switched readInt32LEreadUInt32LE for runCount, focusCount, and focusMs fields; correctly treats Windows DWORD counters as unsigned so high-bit values no longer produce negative numbers.
desktop/windows/src/main/fileIndex/scanRules.test.ts Adds a test block covering Node_Modules, .GIT, and __PYCACHE__ mixed-case inputs; pairs correctly with the implementation change.
desktop/windows/src/main/usage/userAssist.test.ts Test helper blob() updated to use writeUInt32LE; new test covers values > INT32_MAX (3B/4B) to directly validate the unsigned-read fix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Directory entry name] --> B["name.toLowerCase()"]
    B --> C{SKIP_DIRS.has?}
    C -- yes --> D[Skip directory]
    C -- no --> E{depth <= MAX_DEPTH?}
    E -- yes --> F[Descend into directory]
    E -- no --> G[Stop recursion]

    H[UserAssist registry blob] --> I["readUInt32LE(OFF_RUN_COUNT)"]
    H --> J["readUInt32LE(OFF_FOCUS_COUNT)"]
    H --> K["readUInt32LE(OFF_FOCUS_MS)"]
    I --> L[runCount: 0..4294967295]
    J --> M[focusCount: 0..4294967295]
    K --> N["focusSeconds = round(focusMs / 1000)"]
    N --> O[Aggregate by friendly app name]
    O --> P[Sort by focusSeconds desc]
Loading

Reviews (1): Last reviewed commit: "fix(windows): harden file index and User..." | Re-trigger Greptile

Comment thread desktop/windows/src/main/fileIndex/scanRules.ts Outdated
@tianmind-studio tianmind-studio force-pushed the codex/windows-index-usage-edge-cases branch from d26d773 to 5d899c3 Compare June 16, 2026 23:44
@tianmind-studio tianmind-studio force-pushed the codex/windows-index-usage-edge-cases branch from 5d899c3 to 86dfe2e Compare June 17, 2026 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant