Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/git-status-untracked-all.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/agent-core-v2": patch
---

Fix git status collapsing untracked directories: files created inside an untracked directory now appear individually in the Changes panel instead of being hidden behind the directory entry.
6 changes: 4 additions & 2 deletions packages/agent-core-v2/src/app/git/gitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
* `git` domain (L1) — `IGitService` implementation.
*
* Runs `git status` / `git diff` (and `gh pr view`) against a repository on
* the local disk. Process spawning goes through the App-scope
* the local disk; status passes `--untracked-files=all` so files inside
* untracked directories surface individually instead of collapsing into the
* directory entry. Process spawning goes through the App-scope
Comment on lines +5 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 Badge Remove implementation flag detail from header

This new header clause documents the exact git status flag used rather than the module's external role/responsibility, so it violates the v2 comment convention and can drift the next time status spawning changes. Please keep the observable behavior covered by the test/code and avoid naming the implementation flag in the module header.

AGENTS.md reference: packages/agent-core-v2/AGENTS.md:L13-L13

Useful? React with 👍 / 👎.

* `IHostProcessService` from `os/interface`, and the single path-existence
* probe in `diff` goes through `IHostFileSystem`; no Node platform API is
* imported directly. Bound at App scope — it owns no Session dependency, so
Expand Down Expand Up @@ -45,7 +47,7 @@ export class GitService implements IGitService {
throw this.gitUnavailable(cwd, inside.stderr.trim() || `git rev-parse exit ${inside.exitCode}`);
}

const porc = await this.runCommand('git', ['status', '--porcelain=v1', '--branch'], cwd);
const porc = await this.runCommand('git', ['status', '--porcelain=v1', '--branch', '--untracked-files=all'], cwd);
if (porc.exitCode !== 0) {
throw this.gitUnavailable(cwd, porc.stderr.trim() || `git status exit ${porc.exitCode}`);
}
Expand Down
12 changes: 11 additions & 1 deletion packages/agent-core-v2/test/app/git/gitService.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { execFileSync } from 'node:child_process';
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';

Expand Down Expand Up @@ -92,6 +92,16 @@ describe('GitService', () => {
expect(result.entries).toEqual({ 'a.txt': 'modified' });
});

it('lists files inside untracked directories individually', async () => {
writeFileSync(join(repo, 'a.txt'), 'a\n');
commitAll('init');
mkdirSync(join(repo, 'newdir'), { recursive: true });
writeFileSync(join(repo, 'newdir', 'b.txt'), 'b\n');

const result = await service.status(repo);
expect(result.entries).toEqual({ 'newdir/b.txt': 'untracked' });
});

it('throws FS_GIT_UNAVAILABLE when not a repo', async () => {
const notRepo = mkdtempSync(join(tmpdir(), 'not-repo-'));
try {
Expand Down
Loading