Skip to content

Commit fa80c15

Browse files
committed
fix(mcp): git repository probe reads stable English diagnostics
The probe that tells a non-git folder apart matches git's "not a git repository" text, which git translates on a localized host. It now runs with LC_ALL=C, as the git driver's own stderr checks do, so a non-git folder keeps main on any locale.
1 parent 2c4c5ba commit fa80c15

2 files changed

Lines changed: 71 additions & 10 deletions

File tree

‎apps/server/src/mcp/OrchestratorMcpService.test.ts‎

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,16 +2375,23 @@ describe("OrchestratorMcpService scheduled tasks that launch a fresh worktree pe
23752375
const lastWorkspaceStrategy = (upserts: Ref.Ref<ReadonlyArray<ScheduledTaskUpsertInput>>) =>
23762376
Ref.get(upserts).pipe(Effect.map((all) => all.at(-1)?.workspaceStrategy));
23772377

2378-
const expectBase = (workspaceRoot: string, baseRef: string) =>
2379-
withService(workspaceRoot, (service, upserts) =>
2380-
Effect.gen(function* () {
2381-
yield* scheduleUnbound(service);
2382-
assert.deepStrictEqual(yield* lastWorkspaceStrategy(upserts), {
2383-
type: "worktree",
2384-
baseRef,
2385-
startFromOrigin: true,
2386-
});
2387-
}),
2378+
const expectBase = (
2379+
workspaceRoot: string,
2380+
baseRef: string,
2381+
layerGit: typeof layerRealGit = layerRealGit,
2382+
) =>
2383+
withService(
2384+
workspaceRoot,
2385+
(service, upserts) =>
2386+
Effect.gen(function* () {
2387+
yield* scheduleUnbound(service);
2388+
assert.deepStrictEqual(yield* lastWorkspaceStrategy(upserts), {
2389+
type: "worktree",
2390+
baseRef,
2391+
startFromOrigin: true,
2392+
});
2393+
}),
2394+
layerGit,
23882395
);
23892396

23902397
it.effect("keeps main when it exists, even if origin's default is another branch", () =>
@@ -2454,6 +2461,58 @@ describe("OrchestratorMcpService scheduled tasks that launch a fresh worktree pe
24542461
}).pipe(Effect.provide(NodeServices.layer)),
24552462
);
24562463

2464+
it.effect("keeps main for a project that is not a git repository on a German host", () =>
2465+
Effect.gen(function* () {
2466+
const fileSystem = yield* FileSystem.FileSystem;
2467+
const workspaceRoot = yield* fileSystem.makeTempDirectoryScoped({
2468+
prefix: "t3-mcp-schedule-",
2469+
});
2470+
const localeKeys = ["LANG", "LC_ALL", "LANGUAGE"] as const;
2471+
yield* Effect.acquireRelease(
2472+
Effect.sync(() => {
2473+
const saved = localeKeys.map((key) => [key, process.env[key]] as const);
2474+
process.env.LANG = "de_DE.UTF-8";
2475+
process.env.LC_ALL = "de_DE.UTF-8";
2476+
process.env.LANGUAGE = "de";
2477+
return saved;
2478+
}),
2479+
(saved) =>
2480+
Effect.sync(() => {
2481+
for (const [key, value] of saved) {
2482+
if (value === undefined) Reflect.deleteProperty(process.env, key);
2483+
else process.env[key] = value;
2484+
}
2485+
}),
2486+
);
2487+
// Not every git build ships translations, so stand in for a German one:
2488+
// its diagnostics are German unless the call itself forces the C locale.
2489+
const layerGermanGit = Layer.effect(
2490+
GitVcsDriver.GitVcsDriver,
2491+
Effect.gen(function* () {
2492+
const driver = yield* GitVcsDriver.GitVcsDriver;
2493+
return GitVcsDriver.GitVcsDriver.of({
2494+
...driver,
2495+
execute: (input) =>
2496+
driver.execute(input).pipe(
2497+
Effect.map((result) =>
2498+
(input.env?.LC_ALL ?? process.env.LC_ALL) === "C"
2499+
? result
2500+
: {
2501+
...result,
2502+
stderr: result.stderr.replace(
2503+
"not a git repository",
2504+
"kein Git-Repository",
2505+
),
2506+
},
2507+
),
2508+
),
2509+
});
2510+
}),
2511+
).pipe(Layer.provide(layerRealGit));
2512+
yield* expectBase(workspaceRoot, "main", layerGermanGit);
2513+
}).pipe(Effect.provide(NodeServices.layer)),
2514+
);
2515+
24572516
it.effect("fails retryably without saving a base when the git status cannot be read", () =>
24582517
Effect.gen(function* () {
24592518
const fileSystem = yield* FileSystem.FileSystem;

‎apps/server/src/mcp/OrchestratorMcpService.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,8 @@ const make = Effect.gen(function* () {
942942
cwd,
943943
args: ["rev-parse", "--git-dir"],
944944
allowNonZeroExit: true,
945+
// English diagnostics on any host locale, so the stderr check below holds.
946+
env: { LC_ALL: "C" },
945947
}),
946948
);
947949
if (probe.exitCode !== 0) {

0 commit comments

Comments
 (0)