fix(member-work-sync): pass codex turn settled env to mixed teams

This commit is contained in:
777genius 2026-04-29 20:55:40 +03:00
parent 8e7f7bea43
commit 3ce183a229
2 changed files with 67 additions and 0 deletions

View file

@ -4447,6 +4447,25 @@ export class TeamProvisioningService {
}
}
private async buildRuntimeTurnSettledEnvironmentForMembers(
primaryProviderId: TeamProviderId | undefined,
memberSpecs: TeamCreateRequest['members']
): Promise<Record<string, string>> {
const resolvedPrimaryProviderId = resolveTeamProviderId(primaryProviderId);
const needsCodexTurnSettledEnv = memberSpecs.some((member) => {
const memberProviderId = resolveTeamProviderId(
normalizeTeamMemberProviderId(member.providerId) ?? resolvedPrimaryProviderId
);
return memberProviderId === 'codex';
});
if (!needsCodexTurnSettledEnv) {
return {};
}
return this.buildRuntimeTurnSettledEnvironment('codex');
}
private async readRuntimeProviderLaunchFacts(params: {
claudePath: string;
cwd: string;
@ -12861,6 +12880,13 @@ export class TeamProvisioningService {
leadProviderId: request.providerId,
members: materializedMemberSpecs,
});
Object.assign(
shellEnv,
await this.buildRuntimeTurnSettledEnvironmentForMembers(
request.providerId,
allEffectiveMemberSpecs
)
);
const lanePlan = this.planRuntimeLanesOrThrow(request.providerId, allEffectiveMemberSpecs);
const primaryMemberNames = new Set(lanePlan.primaryMembers.map((member) => member.name));
const effectiveMemberSpecs = allEffectiveMemberSpecs.filter((member) =>
@ -13916,6 +13942,13 @@ export class TeamProvisioningService {
leadProviderId: request.providerId,
members: materializedMemberSpecs,
});
Object.assign(
shellEnv,
await this.buildRuntimeTurnSettledEnvironmentForMembers(
request.providerId,
allEffectiveMemberSpecs
)
);
const lanePlan = this.planRuntimeLanesOrThrow(request.providerId, allEffectiveMemberSpecs);
const primaryMemberNames = new Set(lanePlan.primaryMembers.map((member) => member.name));
const effectiveMemberSpecs = allEffectiveMemberSpecs.filter((member) =>

View file

@ -1970,6 +1970,40 @@ describe('TeamProvisioningService prepare/auth behavior', () => {
expect(result.env.AGENT_TEAMS_RUNTIME_TURN_SETTLED_SPOOL_ROOT).toBe('/tmp/runtime-hooks');
});
it('adds Codex turn-settled env when Codex is only a secondary member provider', async () => {
const svc = new TeamProvisioningService();
svc.setRuntimeTurnSettledEnvironmentProvider(async ({ provider }) =>
provider === 'codex'
? { AGENT_TEAMS_RUNTIME_TURN_SETTLED_SPOOL_ROOT: '/tmp/runtime-hooks' }
: null
);
const result = await (svc as any).buildRuntimeTurnSettledEnvironmentForMembers('anthropic', [
{ name: 'alice', providerId: 'anthropic' },
{ name: 'jack', providerId: 'codex' },
]);
expect(result).toEqual({
AGENT_TEAMS_RUNTIME_TURN_SETTLED_SPOOL_ROOT: '/tmp/runtime-hooks',
});
});
it('does not add Codex turn-settled env when no member uses Codex', async () => {
const svc = new TeamProvisioningService();
const provider = vi.fn(async () => ({
AGENT_TEAMS_RUNTIME_TURN_SETTLED_SPOOL_ROOT: '/tmp/runtime-hooks',
}));
svc.setRuntimeTurnSettledEnvironmentProvider(provider);
const result = await (svc as any).buildRuntimeTurnSettledEnvironmentForMembers('anthropic', [
{ name: 'alice', providerId: 'anthropic' },
{ name: 'bob', providerId: 'gemini' },
]);
expect(result).toEqual({});
expect(provider).not.toHaveBeenCalled();
});
it('allows help-env resolution to continue even when provisioning env warns', async () => {
const svc = new TeamProvisioningService();
vi.spyOn(svc as any, 'buildProvisioningEnv').mockResolvedValue({