Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions apps/server/src/provider/Drivers/CodexDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function makeCodexMaintenanceResolver(sharedHomePath: string) {
nativeUpdate: {
args: ["update"],
isCommandPath: isCodexStandaloneCommandPath,
requiresCommandPath: true,
env: { CODEX_HOME: sharedHomePath },
},
});
Expand Down
33 changes: 33 additions & 0 deletions packages/provider-core/src/server/maintenanceResolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,39 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => {
}),
);

it.effect(
"keeps an unrecognized install manual-only when the native updater requires its path",
() =>
Effect.gen(function* () {
const systemPath =
"/usr/local/lib/codex/releases/rust-v0.162.1-x86_64-unknown-linux-musl/bin/codex";
const capabilities = yield* resolvePackageManagedProviderMaintenance(
{
provider: driver("codex"),
npmPackageName: "@openai/codex",
nativeUpdate: {
args: ["update"],
isCommandPath: isNativeTestCommandPath("/packages/standalone/"),
requiresCommandPath: true,
},
},
{
binaryPath: "codex",
resolvedCommandPath: "/usr/local/bin/codex",
realCommandPath: systemPath,
env: {},
platform: "linux",
},
).pipe(
Effect.provideService(HostProcess.Platform, "linux"),
Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn),
);

expect(capabilities.update).toBeNull();
expect(capabilities.installPath).toBe(systemPath);
}),
);

const claudeUpdate = {
provider: driver("claudeAgent"),
npmPackageName: "@anthropic-ai/claude-code",
Expand Down
12 changes: 7 additions & 5 deletions packages/provider-core/src/server/maintenanceResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ export interface PackageManagedProviderMaintenanceDefinition {
readonly nativeUpdate: {
readonly args: ReadonlyArray<string>;
readonly isCommandPath?: (commandPath: string) => boolean;
/** The updater cannot detect installs outside `isCommandPath`, so leave those manual-only. */
readonly requiresCommandPath?: boolean;
readonly env?: NodeJS.ProcessEnv;
} | null;
}
Expand Down Expand Up @@ -474,11 +476,11 @@ export const resolvePackageManagedProviderMaintenance = Effect.fn(
}
// A `node_modules` path not proven below belongs to another package or a
// project, so the provider's own updater could act on the wrong install.
const fallback = commandPaths.some((commandPath) =>
normalizeCommandPath(commandPath).includes("/node_modules/"),
)
? manual
: native;
const fallback =
nativeUpdate?.requiresCommandPath ||
commandPaths.some((commandPath) => normalizeCommandPath(commandPath).includes("/node_modules/"))
? manual
: native;
if (commandPaths.some(isVitePlusGlobalCommandPath)) {
return makeProviderMaintenanceCapabilities({
provider: definition.provider,
Expand Down
Loading