Skip to content

fix(windows): cache rooted path probes and UNC globs#582

Merged
Astro-Han merged 1 commit into
devfrom
slock/windows-path-canonicalization-cache
May 12, 2026
Merged

fix(windows): cache rooted path probes and UNC globs#582
Astro-Han merged 1 commit into
devfrom
slock/windows-path-canonicalization-cache

Conversation

@Astro-Han
Copy link
Copy Markdown
Owner

@Astro-Han Astro-Han commented May 12, 2026

Summary

Cache repeated Windows rooted-but-driveless canonicalization probes and close the remaining UNC validation gap in the external-directory permission path.

Changes included:

  • cache successful rooted-but-driveless Windows probe results, with cache invalidation when the cached target disappears or the default Windows root environment changes
  • normalize Windows UNC glob patterns with path.win32 so \\server\share\... permission scopes do not collapse to *
  • add deterministic tests for cache reuse/invalidation, extended UNC path normalization, and UNC permission-glob generation

Why

Issue #497 left two bounded Windows follow-ups after #493:

  1. repeated rooted-but-driveless canonicalization still re-probed drive roots on every hit
  2. UNC / extended UNC validation was still incomplete, especially around permission-glob generation

This PR keeps the fix inside that P3 follow-up surface. It does not reopen #427 correctness work, wildcard semantics, or broader path architecture.

Related Issue

Closes #497.

Human Review Status

Pending. A human should make the final merge decision after reviewing the final diff and verification evidence.

Review Focus

  • whether the rooted-but-driveless cache only changes repeated Windows probe behavior and stays conservative on invalidation
  • whether Windows UNC and extended UNC permission paths now preserve the share root all the way through glob generation
  • whether the patch stays bounded to Windows-only canonicalization / permission-path logic

Risk Notes

  • Windows-only behavior change in path canonicalization and external-directory permission glob generation
  • the cache stores only successful rooted-but-driveless matches; misses and ambiguities still probe live
  • no live Windows UNC host was available locally, so UNC validation is deterministic unit coverage rather than an interactive Windows smoke

How To Verify

Core Windows normalization tests: bun --cwd packages/core test test/filesystem/normalize-path.test.ts -> 9 passed, 7 skipped
Guarded-tool boundary suite: bun --cwd packages/opencode test test/tool/external-directory.test.ts test/tool/read.test.ts test/tool/write.test.ts test/tool/edit.test.ts test/tool/apply_patch.test.ts test/tool/glob.test.ts test/tool/grep.test.ts test/tool/lsp.test.ts -> 135 passed
Core typecheck: bun --cwd packages/core typecheck -> exit 0
Opencode typecheck: bun --cwd packages/opencode typecheck -> exit 0
Diff check: git diff --check -> exit 0
Validation recorded in tests: packages/core/test/filesystem/normalize-path.test.ts and packages/opencode/test/tool/external-directory.test.ts

Screenshots or Recordings

None. No visible UI changes.

Checklist

  • Human review status is stated above as pending, approved, or not required
  • I linked the related issue, or stated why there is no issue
  • This PR has type, primary area, and priority labels, or I requested maintainer labeling
  • I described the review focus and any meaningful risks
  • I listed the relevant verification steps and the key result for each
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant
  • I reviewed the final diff for unrelated changes and suspicious dependency changes
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • Bug Fixes

    • Improved Windows path handling to preserve extended UNC roots and produce correct Windows-style glob patterns; fixed directory canonicalization to retain share roots.
  • Performance

    • Added/refined caching for Windows path resolution to reduce redundant filesystem probes and refresh correctly when drive context changes.
  • Tests

    • Expanded Windows-only tests covering UNC/extended paths and caching/refresh behavior.

Review Change Stack

@Astro-Han Astro-Han added tech-debt Internal cleanup and maintainability debt platform Electron shell, OS integration, packaging, updater, signing, paths, and permissions P3 Low priority windows Windows-specific labels May 12, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 25094dd6-4a8c-4a34-b7fe-31eba73254c0

📥 Commits

Reviewing files that changed from the base of the PR and between 725854b and fb121ed.

📒 Files selected for processing (4)
  • packages/core/src/filesystem.ts
  • packages/core/test/filesystem/normalize-path.test.ts
  • packages/opencode/src/tool/external-directory.ts
  • packages/opencode/test/tool/external-directory.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/core/test/filesystem/normalize-path.test.ts
  • packages/opencode/src/tool/external-directory.ts
  • packages/core/src/filesystem.ts

📝 Walkthrough

Walkthrough

Refactors Windows path handling to use fs.realpathSync.native, constructs Windows-style wildcard patterns with win32.join, introduces an optional cache plus internal cache-invalidating logic for rooted-but-driveless path resolution, adjusts external-directory dirname selection on Windows, and adds Windows-only tests for UNC/extended UNC and caching behavior.

Changes

Windows Path Normalization and Caching

Layer / File(s) Summary
Switch to fs realpath and Windows pattern join
packages/core/src/filesystem.ts
Replace named fs exports with * as fs; update normalizePath, normalizePathPattern, and resolve to use fs.realpathSync.native and build wildcard suffixes with win32.join for Windows patterns.
Windows rooted-variant cache and options
packages/core/src/filesystem.ts
Add cache?: Map<string,string> to WindowsPathOptions; introduce internal default cache and an environment-key, refresh/clear default cache when drive context (cwd root or process.env.SystemDrive) changes, and select between caller cache and default cache for lookups and population.
Core Windows normalization tests
packages/core/test/filesystem/normalize-path.test.ts
Add Windows-only tests: UNC glob-root preservation for normalizePathPattern, and caching behavior test for rooted-but-driveless path resolution (probe counting, reuse, and cache invalidation via driveRoots change).
External-directory dirname selection
packages/opencode/src/tool/external-directory.ts
When options.kind === "file", compute dir using platform-appropriate dirname (path.win32.dirname on Windows, path.dirname otherwise) and use that base for Windows glob construction via path.win32.join and normalization.
External-directory Windows tests
packages/opencode/test/tool/external-directory.test.ts
Add Win32-only tests: canonicalize extended UNC into standard UNC for assertExternalDirectory (assert glob patterns and metadata paths) and preserve \\server\share root in resolveExternalPathForPermission.

Possibly related issues

Possibly related PRs

  • Astro-Han/pawwork#493: Earlier PR that implemented Windows path normalization improvements which this change extends (caching and native realpath use).
  • Astro-Han/pawwork#431: Modifies rooted-but-driveless path resolution in the same packages/core/src/filesystem.ts area.

Suggested labels

bug, P2

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hop through UNC and Windows trails,
mapping roots and caching tails,
realpaths found and globs aligned,
drive keys checked, no root left blind,
tests applaud — the path prevails.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(windows): cache rooted path probes and UNC globs' accurately summarizes the main changes: implementing caching for Windows path probes and fixing UNC glob normalization.
Description check ✅ Passed The PR description comprehensively addresses the template with clear summary, rationale, linked issue, review focus, risk notes, and verification steps. All major sections are present and detailed.
Linked Issues check ✅ Passed The PR successfully implements both objectives from #497: caching rooted-but-driveless probe results with conservative invalidation strategy, and closing UNC/extended-UNC validation gaps through path normalization and deterministic tests.
Out of Scope Changes check ✅ Passed All changes are scoped to Windows-only canonicalization and external-directory permission logic. No unrelated refactors, dependencies, or architecture rewrites are introduced; changes stay within the bounded P3 follow-up surface.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch slock/windows-path-canonicalization-cache

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added harness Model harness, prompts, tool descriptions, and session mechanics and removed platform Electron shell, OS integration, packaging, updater, signing, paths, and permissions labels May 12, 2026
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

Copy link
Copy Markdown
Owner Author

@Astro-Han Astro-Han left a comment

Choose a reason for hiding this comment

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

GLM First-pass Review

P0-P3 Severity Analysis: No P0/P1/P2/P3 issues found.

Spec Verification

Spec Item Implementation Status
Rooted-driveless cache hit logic cache.get + exists check Covered
Cache invalidation on target disappearance cache.delete when !exists Covered
Cache invalidation on cwd root change refreshRootedWindowsVariantCache compares cwdRoot Covered
Cache invalidation on SystemDrive change envKey includes systemDrive Covered
UNC share root preserved in glob path.win32.dirname/join for UNC paths Covered
Extended UNC glob normalization Test verifies UNC path handling Covered
Windows-only (no macOS/Linux impact) process.platform !== win32 early return Covered

Test Coverage

  • Cache reuse: normalize-path.test.ts verifies probe count reduction
  • Cache invalidation: Test verifies refreshed result after live.set
  • Extended UNC: normalizePathPattern test
  • UNC glob: external-directory.test.ts verifies patterns/always preserve share root

Summary

  • 4 files +141/-8, minimal scope
  • Cache hit/invalidation paths complete
  • UNC glob correctly preserves share root
  • Tests cover all 4 boundary cases
  • No macOS/Linux path behavior changes

No blocking issues. Ready for second-pass review.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a caching mechanism for resolving rooted-but-driveless Windows paths to improve performance and ensures consistent use of win32 path methods and fs.realpathSync.native for better Windows compatibility, especially regarding UNC paths. Corresponding tests were added to verify these changes. Feedback was provided to simplify the cache key generation by removing a redundant string replacement that is already handled by the path normalization function.

Comment thread packages/core/src/filesystem.ts Outdated
Copy link
Copy Markdown
Owner Author

@Astro-Han Astro-Han left a comment

Choose a reason for hiding this comment

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

Second-pass (product / scope) review.

Three-question check passes: change stays narrow (4 files +141/-8), cache invalidation covers cached-target removal / cwd-root change / SystemDrive change, UNC glob fix routes consistently through path.win32, and resetWindowsRootedVariantCacheForTest is test-only.

One P3 clarification, non-blocking:

packages/core/src/filesystem.ts resolve() switched its realpath call from realpathSync(resolved) to fs.realpathSync.native(resolved). This isn't called out in the PR Review Focus or in issue #497's spec. It looks like an intentional consistency tweak (so resolve() matches canonicalize() which already used .native), but please confirm:

  1. Is this intentional, not an unintended side effect of the import * as fs from "fs" refactor?
  2. Are the existing tests covering .native behavior on Windows for symlink / junction / ENOENT / non-existent paths, given .native and the JS-shim variant can diverge on edge cases?

If intentional and behaviorally equivalent for the cases we care about, this is fine to keep as a small scope-aligned perf nudge. If accidental, please revert that single line to keep PR scope tight.

No P0 / P1 / P2 findings. Awaiting GPT-X engineering final review.

@Astro-Han Astro-Han force-pushed the slock/windows-path-canonicalization-cache branch from 554e12b to 725854b Compare May 12, 2026 14:06
@Astro-Han Astro-Han force-pushed the slock/windows-path-canonicalization-cache branch from 725854b to fb121ed Compare May 12, 2026 14:11
@Astro-Han Astro-Han merged commit ddab268 into dev May 12, 2026
24 checks passed
@Astro-Han Astro-Han deleted the slock/windows-path-canonicalization-cache branch May 12, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

harness Model harness, prompts, tool descriptions, and session mechanics P3 Low priority tech-debt Internal cleanup and maintainability debt windows Windows-specific

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task] Follow up Windows path canonicalization caching and live UNC validation

1 participant