Skip to content
This repository was archived by the owner on Feb 25, 2026. It is now read-only.

fix: use path normalization to fix win32 issues#108

Closed
pschiel wants to merge 8 commits intoKilo-Org:devfrom
pschiel:windows-posix-paths
Closed

fix: use path normalization to fix win32 issues#108
pschiel wants to merge 8 commits intoKilo-Org:devfrom
pschiel:windows-posix-paths

Conversation

@pschiel
Copy link
Contributor

@pschiel pschiel commented Feb 4, 2026

Fixes Kilo-Org/kilocode#6332

In reference to anomalyco/opencode#6763

Summary

This fix solves a whole series of bugs, resulting from filepath issues with backslashes occuring on Windows.

Solution: normalize all internal paths to forward slashes using centralized Filesystem wrappers

Why this works: all win32 shells work with forward slash paths, this is de-facto industry standard (git, vscode, cmake, ... all use this pattern)

Observed issues

  • git rev-parse --show-toplevel returns E:/x/y forward slash format → worktree/directory mismatch
  • path.resolve(), path.relative(), realpathSync.native(), realpath (bash) break with git bash paths (various issues)
  • /d/x within C drive (/c/) results in things like C:\d\x
  • relative paths not working like expected using cross-drive
  • contains logic not working → issues with permission system and external_directory
  • /tmp inside git bash is something else outside of it
  • tools break using backslash paths (some backslashes get "eaten")
  • escaping hell for agents → requires double/quadruple escaping
  • observed in all win32 native shells (git bash, cmd, powershell/pwsh)
  • few issues in app/desktop (wrong filepath splits/usage)
  • bun hard crashing with segfault when spawn() is used with non-existing directory

Tested with fix

  • local test suite succeeds now with 100% (bun test in packages/opencode)
  • all possible path variants (C:\a\b, C:/a/b, /c/a/b, /cygdrive/c/a/b) are normalized into C:/a/b format
  • full functionality of all tools (ENOENT errors gone, permissions, relative paths, external directory, LSP)
  • worktree/sandbox handling correct
  • tested TUI and desktop
  • bun spawns via bash/pty not segfaulting

How to reproduce/test

  • test suite
  • running prompts with various problematic/mixed filepaths (see attached md example)

Notes

A few more places would require normalization - but they're unused/dead code (should be removed)
Desktop likely having more issues, especially bun.spawn() usage

@marius-kilocode
Copy link
Collaborator

@pschiel Can you confirm this was tested, how you tested it and how I can reproduce?

@pschiel
Copy link
Contributor Author

pschiel commented Feb 4, 2026

@pschiel Can you confirm this was tested, how you tested it and how I can reproduce?

I fixed only issues that were not working, I reproduced all of the errors.

test suite (bun test in packages/opencode) in git bash, cmd and powershell:

your current dev branch:
Screenshot 2026-02-04 021417

with patch:
Screenshot 2026-02-04 025437

other than these, just plenty of usage since ~2 months. backslashes are the biggest problem, relative paths and cross-drive paths. i had a testing command that checked some of these (requires some structure/files setup).

when working in a windows env, it's inevitable that mixed paths come from anywhere, all of them should work:

test-windows-posix-paths.md

@pschiel
Copy link
Contributor Author

pschiel commented Feb 4, 2026

if you require more info / steps to reproduce for a certain tool or so, let me know.

some others were
"run bash tool ls -l with cwd /foo" -> bun segfault (if dir not found, happens regularly)
"write invalid TS file to D:/bla.ts" (cross-drive) -> LSP shows no diagnostics (silent error)
external directory permissions ("accept all") are not stored

issue always same - string matches, contains() checks etc can only work if paths are internally normalized

@pschiel
Copy link
Contributor Author

pschiel commented Feb 4, 2026

you might want to look packages\app\src\custom-elements.d.ts again.

this is a symlink in the repo, which doesn't work in windows, hence the change into a regular file with export. (I noticed a check failing due to this file in your CI)

@marius-kilocode
Copy link
Collaborator

Interesting that the windows runner tests are failing but passing locally for you

@pschiel
Copy link
Contributor Author

pschiel commented Feb 4, 2026

Interesting that the windows runner tests are failing but passing locally for you

these are just e2e tests which do a few clicks and that's it - I don't think the unit+integration tests run in a win32 runner.

@pschiel
Copy link
Contributor Author

pschiel commented Feb 4, 2026

Since last opencode merge, llm.test.ts fails due to BunProc install on Windows. Install takes much longer on Windows, and is not needed for the tests -> Solution: mock BunProc and Plugin 669fbf1

@pschiel
Copy link
Contributor Author

pschiel commented Feb 5, 2026

e963daa fixes the cause of the test (linux) fails:

KILO_API_KEY and KILO_ORG_ID are not set in the branch pipeline, but required for tests:

-> no providers connect -> model list is empty -> model picker has no list items -> 4 model picker tests fail

added a check for these vars and skipping the 4 tests so the pipeline is green - if you fix the credentials issue they should run

@pschiel
Copy link
Contributor Author

pschiel commented Feb 5, 2026

the other issue was that the two custom-elements.d.ts files still had type 120000 in git (symlink) but need to be 100644 (regular files)

reason for changing was: symlinks don't work reliably on windows, and vite will fail reading them. changing into regular files with an export works

@pschiel
Copy link
Contributor Author

pschiel commented Feb 5, 2026

all unit/integration tests pass again

 1011 pass
 1 skip
 0 fail

@pschiel
Copy link
Contributor Author

pschiel commented Feb 5, 2026

General Rebase/Conflict info

entire patch is 1 rule "normalize paths on win32 systems via Filesystem wrapper, where otherwise things will break"

  • use Filesystem.normalize() around paths that are stored internally, used for matching, or passed to tools
  • use Filesystem.join() instead if path.join() ONLY when segments are absolute paths and should be converted, otherwise use Filesystem.normalize(path.join(...))
  • use Filesystem.relative() instead of path.relative()
  • use Filesystem.resolve() instead of path.resolve()
  • use Filesystem.dirname() instead of path.dirname()
  • use Filesystem.realpath() instead of fs.realpath() or fs.realpathSync

@pschiel pschiel force-pushed the windows-posix-paths branch from b269132 to 70b7679 Compare February 20, 2026 18:02
@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Feb 20, 2026

Code Review Summary

Status: No New Issues Found | Recommendation: Merge

All previously reported issues have been addressed in subsequent commits:

  • realpath catch block now normalizes via normalize(p)
  • permission.tsx normalization is now consistent — absolute paths wrapped in Filesystem.normalize() and path.sep replaced with '/'
  • read.ts semantic change from path.resolve to Filesystem.join was corrected ✅
  • Windows-only tests wrapped in test.skipIf(process.platform !== "win32")

The normalize function in packages/util/src/path.ts correctly guards with process.platform !== "win32" early return, so it's safe on all platforms.

Files Reviewed (33 files)
  • packages/app/src/custom-elements.d.ts — symlink replaced with file copy for Windows compatibility
  • packages/opencode/src/agent/agent.tspath.join/path.relativeFilesystem.join/Filesystem.relative
  • packages/opencode/src/cli/cmd/tui/routes/session/index.tsx — path operations migrated to Filesystem.*
  • packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx — normalization fixes applied
  • packages/opencode/src/config/config.tsrel() now normalizes both item and pattern
  • packages/opencode/src/file/ignore.ts — normalize filepath, split on / instead of sep
  • packages/opencode/src/kilocode/paths.tspath.joinFilesystem.join
  • packages/opencode/src/lsp/client.tsnormalizePathrealpath
  • packages/opencode/src/tool/external-directory.ts — normalize target, use Filesystem.dirname/join
  • packages/opencode/src/tool/glob.ts — path operations migrated to Filesystem.*
  • packages/opencode/src/tool/grep.ts — path operations migrated to Filesystem.*
  • packages/opencode/src/tool/ls.ts — path operations migrated to Filesystem.*
  • packages/opencode/src/tool/lsp.ts — path operations migrated to Filesystem.*
  • packages/opencode/src/tool/multiedit.tspath.relativeFilesystem.relative
  • packages/opencode/src/tool/plan.tspath.relativeFilesystem.relative
  • packages/opencode/src/tool/read.ts — normalize input, use Filesystem.* throughout
  • packages/opencode/src/tool/truncation.tspath.joinFilesystem.join
  • packages/opencode/src/tool/write.ts — normalize input, use Filesystem.* throughout
  • packages/opencode/src/util/filesystem.ts — core changes: new normalize, relative, resolve, join, dirname; renamed normalizePathrealpath; removed unused overlaps
  • packages/opencode/test/config/config.test.ts — Windows-specific baseUrl handling
  • packages/opencode/test/fixture/fixture.tsFilesystem.normalize for realpath, better git error handling
  • packages/opencode/test/ide/ide.test.tsstructuredClone → shallow copy for process.env
  • packages/opencode/test/project/project.test.ts — normalize paths in assertions
  • packages/opencode/test/session/llm.test.ts — mock BunProc/Plugin, fix server request matching
  • packages/opencode/test/skill/skill.test.ts — normalize paths in assertions
  • packages/opencode/test/snapshot/snapshot.test.ts — Windows MAX_PATH and symlink handling
  • packages/opencode/test/tool/bash.test.ts — normalize paths in assertions, Windows temp dir
  • packages/opencode/test/tool/external-directory.test.tsFilesystem.join/dirname in assertions
  • packages/opencode/test/tool/read.test.ts — normalize paths in assertions
  • packages/opencode/test/tool/registry.test.ts@kilocode/plugin version ^0.0.0*
  • packages/opencode/test/util/filesystem.test.ts — new Windows-only tests for normalize/relative/join/dirname/contains
  • packages/ui/src/components/message-part.tsx — normalize filePath for diagnostics lookup with fallback
  • packages/util/src/path.ts — new normalize function with platform guard

@pschiel pschiel force-pushed the windows-posix-paths branch from 70b7679 to 2576353 Compare February 20, 2026 18:14
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
@pschiel
Copy link
Contributor Author

pschiel commented Feb 20, 2026

Windows Unit Tests (not running in pipeline):
bun test

 1195 pass
 5 skip
 3 fail

Failing tests due to 5sec timeout - bun install needs more on Windows.
Pass with:
bun test --timeout=20000 test/tool/registry.test.ts
bun test --timeout=20000 test/provider/amazon-bedrock.test.ts

@markijbema
Copy link
Contributor

Hi! Thank you for taking the time to contribute to this project—we really appreciate it. 🙏

We are currently working on re-platforming the core of our VS Code and JetBrains extensions to be based on our new Kilo CLI, with a complete rebuild based on OpenCode as our new foundation, and the moment has come to promote this repository to become the main repository. To do that, we moved the code from this repository to the kilocode repository.

This unfortunately means we cannot merge this branch here anymore. Please add https://github.com/Kilo-Org/kilocode.git as a remote, and push your branch there and create a new PR in https://github.com/Kilo-Org/kilocode . We unfortunately cannot do this for you as then the PR would not be in your name anymore. If you need any help, feel free to ask on our Discord in #kilo-dev-contributors

Sorry for the inconvenience and thank you for contributing to Kilo!

@markijbema markijbema closed this Feb 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows path issues

3 participants