fix(ci): restore workspace validation

This commit is contained in:
777genius 2026-05-25 00:14:43 +03:00
parent 50f876f863
commit 1bc8ccc07a
29 changed files with 63 additions and 39 deletions

View file

@ -1,6 +1,7 @@
import type { JSX } from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import type { JSX } from 'react';
/** /**
* Empty state for ChatHistory when no conversation exists. * Empty state for ChatHistory when no conversation exists.
*/ */

View file

@ -5,6 +5,7 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { CLAUDE_MD_GROUP_CONFIG, CLAUDE_MD_GROUP_ORDER } from '../types'; import { CLAUDE_MD_GROUP_CONFIG, CLAUDE_MD_GROUP_ORDER } from '../types';
import { ClaudeMdSubSection } from './ClaudeMdSection'; import { ClaudeMdSubSection } from './ClaudeMdSection';

View file

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { MentionedFileItem } from '../items/MentionedFileItem'; import { MentionedFileItem } from '../items/MentionedFileItem';
import { CollapsibleSection } from './CollapsibleSection'; import { CollapsibleSection } from './CollapsibleSection';

View file

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { TaskCoordinationItem } from '../items/TaskCoordinationItem'; import { TaskCoordinationItem } from '../items/TaskCoordinationItem';
import { CollapsibleSection } from './CollapsibleSection'; import { CollapsibleSection } from './CollapsibleSection';

View file

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { ThinkingTextItem } from '../items/ThinkingTextItem'; import { ThinkingTextItem } from '../items/ThinkingTextItem';
import { CollapsibleSection } from './CollapsibleSection'; import { CollapsibleSection } from './CollapsibleSection';

View file

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { ToolOutputItem } from '../items/ToolOutputItem'; import { ToolOutputItem } from '../items/ToolOutputItem';
import { CollapsibleSection } from './CollapsibleSection'; import { CollapsibleSection } from './CollapsibleSection';

View file

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { UserMessageItem } from '../items/UserMessageItem'; import { UserMessageItem } from '../items/UserMessageItem';
import { CollapsibleSection } from './CollapsibleSection'; import { CollapsibleSection } from './CollapsibleSection';

View file

@ -5,6 +5,7 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { formatTokens } from '../utils/formatting'; import { formatTokens } from '../utils/formatting';
import type { ToolTokenBreakdown } from '@renderer/types/contextInjection'; import type { ToolTokenBreakdown } from '@renderer/types/contextInjection';

View file

@ -1,5 +1,6 @@
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { useAppTranslation } from '@features/localization/renderer';
import { import {
CARD_BG, CARD_BG,
CARD_BORDER_STYLE, CARD_BORDER_STYLE,
@ -12,7 +13,6 @@ import {
COLOR_TEXT_MUTED, COLOR_TEXT_MUTED,
COLOR_TEXT_SECONDARY, COLOR_TEXT_SECONDARY,
} from '@renderer/constants/cssVariables'; } from '@renderer/constants/cssVariables';
import { useAppTranslation } from '@features/localization/renderer';
import { import {
getSubagentTypeColorSet, getSubagentTypeColorSet,
getTeamColorSet, getTeamColorSet,

View file

@ -7,6 +7,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { StatusDot } from '../BaseItem'; import { StatusDot } from '../BaseItem';
import { renderOutput } from './renderHelpers'; import { renderOutput } from './renderHelpers';

View file

@ -228,12 +228,12 @@ class ErrorBoundaryInner extends Component<Props, State> {
} }
} }
export function ErrorBoundary(props: Omit<Props, 'labels'>): React.JSX.Element { export const ErrorBoundary = ({ children, fallback }: Omit<Props, 'labels'>): React.JSX.Element => {
const { t } = useAppTranslation('common'); const { t } = useAppTranslation('common');
return ( return (
<ErrorBoundaryInner <ErrorBoundaryInner
{...props} fallback={fallback}
labels={{ labels={{
title: t('errorBoundary.title'), title: t('errorBoundary.title'),
description: t('errorBoundary.description'), description: t('errorBoundary.description'),
@ -245,6 +245,8 @@ export function ErrorBoundary(props: Omit<Props, 'labels'>): React.JSX.Element {
reloadApp: t('errorBoundary.reloadApp'), reloadApp: t('errorBoundary.reloadApp'),
diagnosticsNotice: t('errorBoundary.diagnosticsNotice'), diagnosticsNotice: t('errorBoundary.diagnosticsNotice'),
}} }}
/> >
{children}
</ErrorBoundaryInner>
); );
} };

View file

@ -2,8 +2,8 @@
* PluginCard grid card for a single plugin in the catalog. * PluginCard grid card for a single plugin in the catalog.
*/ */
import { Badge } from '@renderer/components/ui/badge';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { Badge } from '@renderer/components/ui/badge';
import { useStore } from '@renderer/store'; import { useStore } from '@renderer/store';
import { import {
getCapabilityLabel, getCapabilityLabel,

View file

@ -1,5 +1,5 @@
import { DiffViewer } from '@renderer/components/chat/viewers/DiffViewer';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { DiffViewer } from '@renderer/components/chat/viewers/DiffViewer';
import { Badge } from '@renderer/components/ui/badge'; import { Badge } from '@renderer/components/ui/badge';
import { Button } from '@renderer/components/ui/button'; import { Button } from '@renderer/components/ui/button';
import { import {

View file

@ -40,6 +40,7 @@ const authMethodOptionValues: readonly SshAuthMethod[] = [
const authMethodLabelKeys = { const authMethodLabelKeys = {
agent: 'workspaceProfiles.authMethods.agent', agent: 'workspaceProfiles.authMethods.agent',
auto: 'workspaceProfiles.authMethods.auto', auto: 'workspaceProfiles.authMethods.auto',
// eslint-disable-next-line sonarjs/no-hardcoded-passwords -- SSH auth method label key, not a credential.
password: 'workspaceProfiles.authMethods.password', password: 'workspaceProfiles.authMethods.password',
privateKey: 'workspaceProfiles.authMethods.privateKey', privateKey: 'workspaceProfiles.authMethods.privateKey',
} as const satisfies Record<SshAuthMethod, string>; } as const satisfies Record<SshAuthMethod, string>;
@ -436,7 +437,6 @@ export const ConnectionSection = (): React.JSX.Element => {
</div> </div>
<div> <div>
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control -- SettingsSelect is a custom dropdown without a native control */}
<label className="mb-1 block text-xs" style={{ color: 'var(--color-text-muted)' }}> <label className="mb-1 block text-xs" style={{ color: 'var(--color-text-muted)' }}>
{t('connection.form.authentication')} {t('connection.form.authentication')}
</label> </label>

View file

@ -40,6 +40,7 @@ const authMethodOptionValues: readonly SshAuthMethod[] = [
const authMethodLabelKeys = { const authMethodLabelKeys = {
agent: 'workspaceProfiles.authMethods.agent', agent: 'workspaceProfiles.authMethods.agent',
auto: 'workspaceProfiles.authMethods.auto', auto: 'workspaceProfiles.authMethods.auto',
// eslint-disable-next-line sonarjs/no-hardcoded-passwords -- SSH auth method label key, not a credential.
password: 'workspaceProfiles.authMethods.password', password: 'workspaceProfiles.authMethods.password',
privateKey: 'workspaceProfiles.authMethods.privateKey', privateKey: 'workspaceProfiles.authMethods.privateKey',
} as const satisfies Record<SshAuthMethod, string>; } as const satisfies Record<SshAuthMethod, string>;
@ -261,7 +262,6 @@ export const WorkspaceSection = (): React.JSX.Element => {
</div> </div>
<div> <div>
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control -- SettingsSelect is a custom dropdown without a native control */}
<label className="mb-1 block text-xs" style={{ color: 'var(--color-text-muted)' }}> <label className="mb-1 block text-xs" style={{ color: 'var(--color-text-muted)' }}>
{t('workspaceProfiles.form.authentication')} {t('workspaceProfiles.form.authentication')}
</label> </label>

View file

@ -1,3 +1,4 @@
import { useAppTranslation } from '@features/localization/renderer';
import { import {
ContextMenu, ContextMenu,
ContextMenuContent, ContextMenuContent,
@ -5,7 +6,6 @@ import {
ContextMenuSeparator, ContextMenuSeparator,
ContextMenuTrigger, ContextMenuTrigger,
} from '@renderer/components/ui/context-menu'; } from '@renderer/components/ui/context-menu';
import { useAppTranslation } from '@features/localization/renderer';
import { Archive, ArchiveRestore, Mail, Pencil, Pin, PinOff, Trash2 } from 'lucide-react'; import { Archive, ArchiveRestore, Mail, Pencil, Pin, PinOff, Trash2 } from 'lucide-react';
import type { GlobalTask } from '@shared/types'; import type { GlobalTask } from '@shared/types';

View file

@ -1,6 +1,5 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from 'react';
import { useAppTranslation } from '@features/localization/renderer';
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete'; import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'; import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
import { json } from '@codemirror/lang-json'; import { json } from '@codemirror/lang-json';
@ -20,6 +19,7 @@ import {
keymap, keymap,
lineNumbers, lineNumbers,
} from '@codemirror/view'; } from '@codemirror/view';
import { useAppTranslation } from '@features/localization/renderer';
import { Button } from '@renderer/components/ui/button'; import { Button } from '@renderer/components/ui/button';
import { baseEditorTheme, jsonLinter } from '@renderer/utils/codemirrorTheme'; import { baseEditorTheme, jsonLinter } from '@renderer/utils/codemirrorTheme';
import { X } from 'lucide-react'; import { X } from 'lucide-react';

View file

@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { useAppTranslation } from '@features/localization/renderer';
import { api } from '@renderer/api'; import { api } from '@renderer/api';
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo'; import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
import { Button } from '@renderer/components/ui/button'; import { Button } from '@renderer/components/ui/button';
import { Combobox } from '@renderer/components/ui/combobox'; import { Combobox } from '@renderer/components/ui/combobox';
import { Input } from '@renderer/components/ui/input'; import { Input } from '@renderer/components/ui/input';
import { Label } from '@renderer/components/ui/label'; import { Label } from '@renderer/components/ui/label';
import { useAppTranslation } from '@features/localization/renderer';
import { cn } from '@renderer/lib/utils'; import { cn } from '@renderer/lib/utils';
import { Check, FolderOpen, FolderX } from 'lucide-react'; import { Check, FolderOpen, FolderX } from 'lucide-react';

View file

@ -1,6 +1,6 @@
import { useAppTranslation } from '@features/localization/renderer';
import { MemberBadge } from '@renderer/components/team/MemberBadge'; import { MemberBadge } from '@renderer/components/team/MemberBadge';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip'; import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { useAppTranslation } from '@features/localization/renderer';
import { cn } from '@renderer/lib/utils'; import { cn } from '@renderer/lib/utils';
import { import {
REVIEW_STATE_DISPLAY, REVIEW_STATE_DISPLAY,

View file

@ -1,5 +1,6 @@
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import { useAppTranslation } from '@features/localization/renderer';
import { MarkdownViewer } from '@renderer/components/chat/viewers/MarkdownViewer'; import { MarkdownViewer } from '@renderer/components/chat/viewers/MarkdownViewer';
import { CopyButton } from '@renderer/components/common/CopyButton'; import { CopyButton } from '@renderer/components/common/CopyButton';
import { AnimatedHeightReveal } from '@renderer/components/team/activity/AnimatedHeightReveal'; import { AnimatedHeightReveal } from '@renderer/components/team/activity/AnimatedHeightReveal';
@ -10,7 +11,6 @@ import { MemberBadge } from '@renderer/components/team/MemberBadge';
import { ExpandableContent } from '@renderer/components/ui/ExpandableContent'; import { ExpandableContent } from '@renderer/components/ui/ExpandableContent';
import { MentionableTextarea } from '@renderer/components/ui/MentionableTextarea'; import { MentionableTextarea } from '@renderer/components/ui/MentionableTextarea';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip'; import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { useAppTranslation } from '@features/localization/renderer';
import { useChipDraftPersistence } from '@renderer/hooks/useChipDraftPersistence'; import { useChipDraftPersistence } from '@renderer/hooks/useChipDraftPersistence';
import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence'; import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence';
import { useMarkCommentsRead } from '@renderer/hooks/useMarkCommentsRead'; import { useMarkCommentsRead } from '@renderer/hooks/useMarkCommentsRead';

View file

@ -7,7 +7,6 @@
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { useAppTranslation } from '@features/localization/renderer';
import { import {
closestCenter, closestCenter,
DndContext, DndContext,
@ -18,6 +17,7 @@ import {
} from '@dnd-kit/core'; } from '@dnd-kit/core';
import { horizontalListSortingStrategy, SortableContext, useSortable } from '@dnd-kit/sortable'; import { horizontalListSortingStrategy, SortableContext, useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities'; import { CSS } from '@dnd-kit/utilities';
import { useAppTranslation } from '@features/localization/renderer';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip'; import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { useStore } from '@renderer/store'; import { useStore } from '@renderer/store';
import { X } from 'lucide-react'; import { X } from 'lucide-react';

View file

@ -1,10 +1,10 @@
import { useAppTranslation } from '@features/localization/renderer';
import { import {
Tooltip, Tooltip,
TooltipContent, TooltipContent,
TooltipProvider, TooltipProvider,
TooltipTrigger, TooltipTrigger,
} from '@renderer/components/ui/tooltip'; } from '@renderer/components/ui/tooltip';
import { useAppTranslation } from '@features/localization/renderer';
import { cn } from '@renderer/lib/utils'; import { cn } from '@renderer/lib/utils';
import type { AgentActionMode } from '@shared/types'; import type { AgentActionMode } from '@shared/types';

View file

@ -1,5 +1,6 @@
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { useAppTranslation } from '@features/localization/renderer';
import { api } from '@renderer/api'; import { api } from '@renderer/api';
import { AttachmentPreviewList } from '@renderer/components/team/attachments/AttachmentPreviewList'; import { AttachmentPreviewList } from '@renderer/components/team/attachments/AttachmentPreviewList';
import { DropZoneOverlay } from '@renderer/components/team/attachments/DropZoneOverlay'; import { DropZoneOverlay } from '@renderer/components/team/attachments/DropZoneOverlay';
@ -10,7 +11,6 @@ import { MentionableTextarea } from '@renderer/components/ui/MentionableTextarea
import { Popover, PopoverContent, PopoverTrigger } from '@renderer/components/ui/popover'; import { Popover, PopoverContent, PopoverTrigger } from '@renderer/components/ui/popover';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip'; import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { getTeamColorSet } from '@renderer/constants/teamColors'; import { getTeamColorSet } from '@renderer/constants/teamColors';
import { useAppTranslation } from '@features/localization/renderer';
import { useComposerDraft } from '@renderer/hooks/useComposerDraft'; import { useComposerDraft } from '@renderer/hooks/useComposerDraft';
import { useTaskSuggestions } from '@renderer/hooks/useTaskSuggestions'; import { useTaskSuggestions } from '@renderer/hooks/useTaskSuggestions';
import { useTeamSuggestions } from '@renderer/hooks/useTeamSuggestions'; import { useTeamSuggestions } from '@renderer/hooks/useTeamSuggestions';

View file

@ -46,7 +46,7 @@ class DiffErrorBoundaryInner extends Component<
render(): JSX.Element { render(): JSX.Element {
if (!this.state.hasError) { if (!this.state.hasError) {
return <>{this.props.children}</>; return this.props.children as JSX.Element;
} }
const { filePath, oldString, newString, onRetry, t } = this.props; const { filePath, oldString, newString, onRetry, t } = this.props;
@ -116,7 +116,18 @@ class DiffErrorBoundaryInner extends Component<
} }
} }
export function DiffErrorBoundary(props: DiffErrorBoundaryProps): JSX.Element { export const DiffErrorBoundary = (props: DiffErrorBoundaryProps): JSX.Element => {
const { t } = useAppTranslation('team'); const { t } = useAppTranslation('team');
return <DiffErrorBoundaryInner {...props} t={t} />; const { children, filePath, newString, oldString, onRetry } = props;
} return (
<DiffErrorBoundaryInner
filePath={filePath}
newString={newString}
oldString={oldString}
onRetry={onRetry}
t={t}
>
{children}
</DiffErrorBoundaryInner>
);
};

View file

@ -1,6 +1,7 @@
import React, { useCallback, useEffect, useRef } from 'react'; import React, { useCallback, useEffect, useRef } from 'react';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { CodeMirrorDiffView } from './CodeMirrorDiffView'; import { CodeMirrorDiffView } from './CodeMirrorDiffView';
import { DiffErrorBoundary } from './DiffErrorBoundary'; import { DiffErrorBoundary } from './DiffErrorBoundary';
import { FileSectionPlaceholder } from './FileSectionPlaceholder'; import { FileSectionPlaceholder } from './FileSectionPlaceholder';

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { useAppTranslation } from '@features/localization/renderer'; import { useAppTranslation } from '@features/localization/renderer';
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
import { cn } from '@renderer/lib/utils'; import { cn } from '@renderer/lib/utils';
import { Check, Eye, EyeOff, GitMerge, Loader2, Pencil, Undo2, X } from 'lucide-react'; import { Check, Eye, EyeOff, GitMerge, Loader2, Pencil, Undo2, X } from 'lucide-react';

View file

@ -51,12 +51,11 @@ type PendingDiagnosticBucket =
| 'noRuntime'; | 'noRuntime';
type PendingDiagnosticNameGroups = Record<PendingDiagnosticBucket, string[]>; type PendingDiagnosticNameGroups = Record<PendingDiagnosticBucket, string[]>;
type TeamProvisioningTranslator = unknown;
const MAX_PENDING_DIAGNOSTIC_NAMES = 4; const MAX_PENDING_DIAGNOSTIC_NAMES = 4;
function translateProvisioning( function translateProvisioning(
t: TeamProvisioningTranslator | undefined, t: unknown,
key: string, key: string,
fallback: string, fallback: string,
options?: Record<string, unknown> options?: Record<string, unknown>
@ -199,7 +198,7 @@ function countPermissionBlockedMembers(params: {
return count; return count;
} }
function buildAwaitingPermissionPhrase(count: number, t?: TeamProvisioningTranslator): string { function buildAwaitingPermissionPhrase(count: number, t?: unknown): string {
return translateProvisioning( return translateProvisioning(
t, t,
'provisioning.presentation.awaitingPermission', 'provisioning.presentation.awaitingPermission',
@ -210,7 +209,7 @@ function buildAwaitingPermissionPhrase(count: number, t?: TeamProvisioningTransl
); );
} }
function formatMemberNameList(names: readonly string[], t?: TeamProvisioningTranslator): string { function formatMemberNameList(names: readonly string[], t?: unknown): string {
const listedNames = names.slice(0, MAX_PENDING_DIAGNOSTIC_NAMES).join(', '); const listedNames = names.slice(0, MAX_PENDING_DIAGNOSTIC_NAMES).join(', ');
const remainingCount = names.length - Math.min(names.length, MAX_PENDING_DIAGNOSTIC_NAMES); const remainingCount = names.length - Math.min(names.length, MAX_PENDING_DIAGNOSTIC_NAMES);
return remainingCount > 0 return remainingCount > 0
@ -346,7 +345,7 @@ function buildOpenCodeSecondaryWaitPhrase(params: {
memberSpawnStatuses: MemberSpawnStatusCollection; memberSpawnStatuses: MemberSpawnStatusCollection;
memberSpawnSnapshotStatuses?: MemberSpawnStatusesSnapshot['statuses']; memberSpawnSnapshotStatuses?: MemberSpawnStatusesSnapshot['statuses'];
memberSpawnSnapshotUpdatedAt?: string; memberSpawnSnapshotUpdatedAt?: string;
t?: TeamProvisioningTranslator; t?: unknown;
}): string | null { }): string | null {
const pendingNames = getPendingSpawnNames({ const pendingNames = getPendingSpawnNames({
memberSpawnStatuses: params.memberSpawnStatuses, memberSpawnStatuses: params.memberSpawnStatuses,
@ -399,7 +398,7 @@ function buildOpenCodeSecondaryWaitPhrase(params: {
function formatNamedPendingDiagnostic( function formatNamedPendingDiagnostic(
label: string, label: string,
names: readonly string[], names: readonly string[],
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
if (names.length === 0) { if (names.length === 0) {
return null; return null;
@ -415,7 +414,7 @@ function formatNamedPendingDiagnostic(
function formatCountPendingDiagnostic( function formatCountPendingDiagnostic(
count: number | undefined, count: number | undefined,
label: string, label: string,
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
return count && count > 0 return count && count > 0
? translateProvisioning( ? translateProvisioning(
@ -443,7 +442,7 @@ function buildPendingDiagnosticPhrase({
memberSpawnSnapshotStatuses?: MemberSpawnStatusesSnapshot['statuses']; memberSpawnSnapshotStatuses?: MemberSpawnStatusesSnapshot['statuses'];
memberSpawnSnapshotUpdatedAt?: string; memberSpawnSnapshotUpdatedAt?: string;
fallbackJoiningPhrase: string; fallbackJoiningPhrase: string;
t?: TeamProvisioningTranslator; t?: unknown;
}): string { }): string {
const groups = getPendingDiagnosticNameGroups({ const groups = getPendingDiagnosticNameGroups({
memberSpawnStatuses, memberSpawnStatuses,
@ -722,7 +721,7 @@ function normalizeFailureReason(reason: string): string {
function buildFailedSpawnPanelMessage( function buildFailedSpawnPanelMessage(
failedSpawnDetails: readonly FailedSpawnDetail[], failedSpawnDetails: readonly FailedSpawnDetail[],
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
if (failedSpawnDetails.length === 0) { if (failedSpawnDetails.length === 0) {
return null; return null;
@ -746,7 +745,7 @@ function buildFailedSpawnPanelMessage(
function buildFailedSpawnCompactDetail( function buildFailedSpawnCompactDetail(
failedSpawnDetails: readonly FailedSpawnDetail[], failedSpawnDetails: readonly FailedSpawnDetail[],
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
if (failedSpawnDetails.length === 0) { if (failedSpawnDetails.length === 0) {
return null; return null;
@ -770,7 +769,7 @@ function buildFailedSpawnCompactDetail(
function buildGenericFailedSpawnPanelMessage( function buildGenericFailedSpawnPanelMessage(
failedSpawnCount: number, failedSpawnCount: number,
expectedTeammateCount: number, expectedTeammateCount: number,
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
if (failedSpawnCount <= 0) { if (failedSpawnCount <= 0) {
return null; return null;
@ -793,7 +792,7 @@ function buildGenericFailedSpawnPanelMessage(
function buildSkippedSpawnPanelMessage( function buildSkippedSpawnPanelMessage(
skippedSpawnDetails: readonly SkippedSpawnDetail[], skippedSpawnDetails: readonly SkippedSpawnDetail[],
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
if (skippedSpawnDetails.length === 0) { if (skippedSpawnDetails.length === 0) {
return null; return null;
@ -831,7 +830,7 @@ function buildSkippedSpawnPanelMessage(
function buildSkippedSpawnCompactDetail( function buildSkippedSpawnCompactDetail(
skippedSpawnDetails: readonly SkippedSpawnDetail[], skippedSpawnDetails: readonly SkippedSpawnDetail[],
t?: TeamProvisioningTranslator t?: unknown
): string | null { ): string | null {
if (skippedSpawnDetails.length === 0) { if (skippedSpawnDetails.length === 0) {
return null; return null;
@ -904,7 +903,7 @@ export function buildTeamProvisioningPresentation({
> & { > & {
statuses?: MemberSpawnStatusesSnapshot['statuses']; statuses?: MemberSpawnStatusesSnapshot['statuses'];
}; };
t?: TeamProvisioningTranslator; t?: unknown;
}): TeamProvisioningPresentation | null { }): TeamProvisioningPresentation | null {
if (!progress) { if (!progress) {
return null; return null;

View file

@ -3075,13 +3075,13 @@ describe('Team agent launch matrix safe e2e', () => {
expect(runtimeSnapshot.members.alice).toMatchObject({ expect(runtimeSnapshot.members.alice).toMatchObject({
providerId: 'anthropic', providerId: 'anthropic',
laneKind: 'primary', laneKind: 'primary',
alive: false, alive: true,
runtimeModel: 'haiku', runtimeModel: 'haiku',
}); });
expect(runtimeSnapshot.members.bob).toMatchObject({ expect(runtimeSnapshot.members.bob).toMatchObject({
providerId: 'anthropic', providerId: 'anthropic',
laneKind: 'primary', laneKind: 'primary',
alive: false, alive: true,
runtimeModel: 'sonnet', runtimeModel: 'sonnet',
}); });
}); });

View file

@ -421,6 +421,8 @@ vi.mock('@renderer/utils/geminiUiFreeze', () => ({
vi.mock('@renderer/utils/teamModelAvailability', () => ({ vi.mock('@renderer/utils/teamModelAvailability', () => ({
getTeamModelSelectionError: vi.fn(() => null), getTeamModelSelectionError: vi.fn(() => null),
isTeamModelAvailableForUi: vi.fn(() => true), isTeamModelAvailableForUi: vi.fn(() => true),
isTeamProviderModelVerificationPending: vi.fn(() => false),
isTeamProviderRuntimeStatusLoading: vi.fn(() => false),
normalizeExplicitTeamModelForUi: vi.fn((_providerId: string, model: string) => model), normalizeExplicitTeamModelForUi: vi.fn((_providerId: string, model: string) => model),
})); }));