fix(team): make launch summary copy honest

This commit is contained in:
777genius 2026-04-23 01:40:51 +03:00
parent 3e53391a73
commit 76fca31fb1
4 changed files with 62 additions and 2 deletions

View file

@ -41,6 +41,7 @@ import { createChipFromSelection } from '@renderer/utils/chipUtils';
import { sumContextInjectionTokens } from '@renderer/utils/contextMath';
import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
import { formatProjectPath } from '@renderer/utils/pathDisplay';
import { buildPendingRuntimeSummaryCopy } from '@renderer/utils/teamLaunchSummaryCopy';
import { buildTaskCountsByOwner, normalizePath } from '@renderer/utils/pathNormalize';
import { nameColorSet } from '@renderer/utils/projectColor';
import { resolveProjectIdByPath } from '@renderer/utils/projectLookup';
@ -263,7 +264,12 @@ const TeamOfflineStatusBanner = memo(function TeamOfflineStatusBanner({
const message =
summary?.teamLaunchState === 'partial_pending'
? summary.runtimeAlivePendingCount != null && summary.runtimeAlivePendingCount > 0
? `Last launch is still reconciling - ${summary.confirmedCount ?? 0}/${summary.expectedMemberCount ?? summary.memberCount} teammates confirmed alive, ${summary.runtimeAlivePendingCount} runtime${summary.runtimeAlivePendingCount === 1 ? '' : 's'} pending bootstrap`
? buildPendingRuntimeSummaryCopy({
confirmedCount: summary.confirmedCount,
expectedMemberCount: summary.expectedMemberCount,
memberCount: summary.memberCount,
runtimeAlivePendingCount: summary.runtimeAlivePendingCount,
})
: 'Last launch is still reconciling'
: summary?.partialLaunchFailure
? summary.missingMemberCount > 0

View file

@ -28,6 +28,7 @@ import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
import { buildTaskCountsByTeam, normalizePath } from '@renderer/utils/pathNormalize';
import { getBaseName } from '@renderer/utils/pathUtils';
import { nameColorSet } from '@renderer/utils/projectColor';
import { buildPendingRuntimeSummaryCopy } from '@renderer/utils/teamLaunchSummaryCopy';
import { isLeadMember } from '@shared/utils/leadDetection';
import {
CheckCircle,
@ -981,7 +982,13 @@ export const TeamListView = (): React.JSX.Element => {
{team.teamLaunchState === 'partial_pending' ? (
<p className="mt-2 text-[11px] text-amber-300">
{team.runtimeAlivePendingCount && team.runtimeAlivePendingCount > 0
? `Last launch is still reconciling — ${team.confirmedCount ?? 0}/${team.expectedMemberCount ?? team.memberCount} teammates confirmed alive, ${team.runtimeAlivePendingCount} runtime${team.runtimeAlivePendingCount === 1 ? '' : 's'} pending bootstrap.`
? buildPendingRuntimeSummaryCopy({
confirmedCount: team.confirmedCount,
expectedMemberCount: team.expectedMemberCount,
memberCount: team.memberCount,
runtimeAlivePendingCount: team.runtimeAlivePendingCount,
includePeriod: true,
})
: 'Last launch is still reconciling.'}
</p>
) : team.partialLaunchFailure || team.teamLaunchState === 'partial_failure' ? (

View file

@ -0,0 +1,17 @@
export function buildPendingRuntimeSummaryCopy(input: {
confirmedCount?: number | null;
expectedMemberCount?: number | null;
memberCount?: number | null;
runtimeAlivePendingCount?: number | null;
includePeriod?: boolean;
}): string {
const pendingCount = input.runtimeAlivePendingCount ?? 0;
if (pendingCount <= 0) {
return input.includePeriod
? 'Last launch is still reconciling.'
: 'Last launch is still reconciling';
}
const expectedCount = input.expectedMemberCount ?? input.memberCount ?? 0;
const message = `Last launch is still reconciling - ${input.confirmedCount ?? 0}/${expectedCount} teammates confirmed alive, ${pendingCount} runtime${pendingCount === 1 ? '' : 's'} still awaiting confirmation`;
return input.includePeriod ? `${message}.` : message;
}

View file

@ -0,0 +1,30 @@
import { describe, expect, it } from 'vitest';
import { buildPendingRuntimeSummaryCopy } from '@renderer/utils/teamLaunchSummaryCopy';
describe('buildPendingRuntimeSummaryCopy', () => {
it('uses generic runtime confirmation wording instead of bootstrap-specific copy', () => {
expect(
buildPendingRuntimeSummaryCopy({
confirmedCount: 2,
expectedMemberCount: 4,
runtimeAlivePendingCount: 2,
})
).toBe(
'Last launch is still reconciling - 2/4 teammates confirmed alive, 2 runtimes still awaiting confirmation'
);
});
it('can emit the punctuated list-card variant', () => {
expect(
buildPendingRuntimeSummaryCopy({
confirmedCount: 1,
expectedMemberCount: 3,
runtimeAlivePendingCount: 1,
includePeriod: true,
})
).toBe(
'Last launch is still reconciling - 1/3 teammates confirmed alive, 1 runtime still awaiting confirmation.'
);
});
});