diff --git a/apps/server/src/provider/Layers/CodexProvider.ts b/apps/server/src/provider/Layers/CodexProvider.ts index d421259b24..56468119da 100644 --- a/apps/server/src/provider/Layers/CodexProvider.ts +++ b/apps/server/src/provider/Layers/CodexProvider.ts @@ -24,6 +24,7 @@ import { ServerSettingsError } from "@t3tools/contracts"; import { createModelCapabilities } from "@t3tools/shared/model"; import { buildServerProvider, type ServerProviderDraft } from "../providerSnapshot.ts"; import { expandHomePath } from "../../pathExpansion.ts"; +import { ServerConfig } from "../../config.ts"; import { scopedSafeTeardown } from "./scopedSafeTeardown.ts"; import packageJson from "../../../package.json" with { type: "json" }; const isCodexAppServerSpawnError = Schema.is(CodexErrors.CodexAppServerSpawnError); @@ -421,6 +422,7 @@ export const checkCodexProviderStatus = Effect.fn("checkCodexProviderStatus")(fu ServerSettingsError, ChildProcessSpawner.ChildProcessSpawner > { + const serverConfig = yield* Effect.serviceOption(ServerConfig); const checkedAt = DateTime.formatIso(yield* DateTime.now); const emptyModels = emptyCodexModelsFromSettings(codexSettings); @@ -444,7 +446,10 @@ export const checkCodexProviderStatus = Effect.fn("checkCodexProviderStatus")(fu const probeResult = yield* probe({ binaryPath: codexSettings.binaryPath, homePath: codexSettings.homePath, - cwd: process.cwd(), + cwd: Option.match(serverConfig, { + onNone: () => process.cwd(), + onSome: (config) => config.cwd, + }), customModels: codexSettings.customModels, environment, }).pipe(Effect.timeoutOption(Duration.millis(PROVIDER_PROBE_TIMEOUT_MS)), Effect.result); diff --git a/apps/server/src/provider/Layers/ProviderRegistry.test.ts b/apps/server/src/provider/Layers/ProviderRegistry.test.ts index 455cac1eb0..48fb02f397 100644 --- a/apps/server/src/provider/Layers/ProviderRegistry.test.ts +++ b/apps/server/src/provider/Layers/ProviderRegistry.test.ts @@ -276,6 +276,28 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsService.layerTest(), T "ProviderRegistry", (it) => { describe("checkCodexProviderStatus", () => { + it.effect("uses configured server cwd for Codex skill discovery when available", () => { + const configuredCwd = `${process.cwd()}-provider-cwd`; + const requestedInputs: Array<{ readonly cwd: string }> = []; + + return checkCodexProviderStatus(defaultCodexSettings, (input) => { + requestedInputs.push({ cwd: input.cwd }); + return Effect.succeed(makeCodexProbeSnapshot()); + }).pipe( + Effect.tap(() => + Effect.sync(() => { + assert.deepStrictEqual(requestedInputs, [{ cwd: configuredCwd }]); + }), + ), + Effect.provide( + Layer.provideMerge( + ServerConfig.layerTest(configuredCwd, { prefix: "t3-provider-registry-" }), + NodeServices.layer, + ), + ), + ); + }); + it.effect("uses the app-server account and model list for provider status", () => Effect.gen(function* () { const status = yield* checkCodexProviderStatus(defaultCodexSettings, () =>