MoonshotAI / MoonshotAI/kimi-code
fs git_status mangles non-ASCII paths (quoted porcelain output parsed verbatim)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Summary
A tracked file whose path contains non-ASCII characters (e.g. output/2026-08-31-总能等到回踩的.md) shows up in the kimi code web/desktop changes tree as a bogus directory chain like:
"my-ai-workspace
output
2026-08-31-bilibili-BV175t86pEre-26.8.31-
346
200
273
...
204.md"
Root cause
git status --porcelain=v1 --branch is invoked without -z in both engines:
- v2:
packages/agent-core-v2/src/app/git/gitService.ts(status()) - v1:
packages/agent-core/src/services/fs/fsGitService.ts(status())
With git's default core.quotePath=true, any path containing non-ASCII bytes is C-quoted in the output:
M "my-ai-workspace/output/...-\346\200\273\350\203\275....md"
parsePorcelain (v2 agent-core-v2/src/app/git/gitParsers.ts, v1 agent-core/src/services/fs/fsGit.ts — the two parsers are byte-identical copies) then:
- takes the quoted string verbatim as the path (never strips the surrounding quotes, never decodes the octal escapes), and
- runs it through a
posix()helper that doesreplaceAll("\\", "/")(v2) /split(path.sep).join("/")(v1, on Windows), which turns every\3xxoctal escape into a fake path segment.
The resulting wire key is "my-ai-workspace/output/...-/346/200/273/.../204.md", which the web/desktop changes tree splits on / — producing the directory chain above.
Impact
- Changes tree renders non-ASCII paths as nonsense directory chains (leading quote glued to the first segment, trailing quote after
.md). - Clicking such a file requests a diff for the mangled path → diff fails.
- Rename entries are mangled the same way (the
-> newhalf stays quoted). pathFiltermatching silently misses these paths.- ASCII-only paths are unaffected.
Reproduced against real git
$ git status --porcelain=v1 --branch
M "my-ai-workspace/output/2026-08-31-bilibili-BV175t86pEre-26.8.31-\346\200\273\350\203\275\347\255\211\345\210\260\345\233\236\350\270\251\347\232\204.md"
$ git status --porcelain=v1 -z | od -c # raw UTF-8, NUL-terminated, never quoted
$ git -c core.quotePath=false status --porcelain=v1
M my-ai-workspace/output/2026-08-31-bilibili-BV175t86pEre-26.8.31-总能等到回踩的.md
With -z, rename records become XY new\0old (new path first, no -> separator).
Suggested fix
Add -z to the porcelain invocation and parse NUL-separated records in parsePorcelain (both engines). The posix() helpers can be dropped entirely — git porcelain already emits / separators on every platform, and keeping them would mangle legitimate POSIX filenames containing backslashes.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with status() in packages/agent-core-v2/src/app/git/gitService.ts and packages/agent-core/src/services/fs/fsGitService.ts, then compare parsePorcelain in the two parser files named in the issue. Trace how porcelain records reach the changes tree, including rename handling. Done means NUL-separated output preserves non-ASCII and backslash-containing paths, while path filtering and renames continue to work in both engines.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, typescript
- Domain
- cli, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100