fix(ci): restore PR #44 checks

This commit is contained in:
777genius 2026-04-13 17:00:49 +03:00
parent 5b328a0f8a
commit a0d87872e7
51 changed files with 183 additions and 208 deletions

View file

@ -12,8 +12,8 @@
}
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0",
"lucide-react": ">=0.300.0"
},
"dependencies": {

View file

@ -531,13 +531,13 @@ importers:
version: 3.0.0
lucide-react:
specifier: '>=0.300.0'
version: 0.577.0(react@18.3.1)
version: 0.577.0(react@19.2.4)
react:
specifier: ^18.0.0
version: 18.3.1
specifier: ^18.0.0 || ^19.0.0
version: 19.2.4
react-dom:
specifier: ^18.0.0
version: 18.3.1(react@18.3.1)
specifier: ^18.0.0 || ^19.0.0
version: 19.2.4(react@19.2.4)
devDependencies:
'@types/d3-force':
specifier: ^3.0.10
@ -9108,11 +9108,6 @@ packages:
rc9@3.0.0:
resolution: {integrity: sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA==}
react-dom@18.3.1:
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies:
react: ^18.3.1
react-dom@19.2.4:
resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
peerDependencies:
@ -9195,10 +9190,6 @@ packages:
react-dom:
optional: true
react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
engines: {node: '>=0.10.0'}
react@19.2.4:
resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
engines: {node: '>=0.10.0'}
@ -9465,9 +9456,6 @@ packages:
resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
engines: {node: '>=11.0.0'}
scheduler@0.23.2:
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
@ -19356,10 +19344,6 @@ snapshots:
dependencies:
yallist: 4.0.0
lucide-react@0.577.0(react@18.3.1):
dependencies:
react: 18.3.1
lucide-react@0.577.0(react@19.2.4):
dependencies:
react: 19.2.4
@ -21160,12 +21144,6 @@ snapshots:
defu: 6.1.4
destr: 2.0.5
react-dom@18.3.1(react@18.3.1):
dependencies:
loose-envify: 1.4.0
react: 18.3.1
scheduler: 0.23.2
react-dom@19.2.4(react@19.2.4):
dependencies:
react: 19.2.4
@ -21259,10 +21237,6 @@ snapshots:
optionalDependencies:
react-dom: 19.2.4(react@19.2.4)
react@18.3.1:
dependencies:
loose-envify: 1.4.0
react@19.2.4: {}
read-binary-file-arch@1.0.6:
@ -21638,10 +21612,6 @@ snapshots:
sax@1.6.0: {}
scheduler@0.23.2:
dependencies:
loose-envify: 1.4.0
scheduler@0.27.0: {}
scslre@0.3.0:

View file

@ -102,12 +102,12 @@ import {
} from './utils/safeWebContentsSend';
import { syncTelemetryFlag } from './sentry';
import {
BranchStatusService,
BoardTaskActivityRecordSource,
BoardTaskActivityService,
BoardTaskExactLogDetailService,
BoardTaskExactLogsService,
BoardTaskLogStreamService,
BranchStatusService,
CliInstallerService,
configManager,
LocalFileSystemProvider,

View file

@ -89,11 +89,11 @@ import { registerValidationHandlers, removeValidationHandlers } from './validati
import { registerWindowHandlers, removeWindowHandlers } from './window';
import type {
BranchStatusService,
BoardTaskActivityService,
BoardTaskLogStreamService,
BoardTaskExactLogDetailService,
BoardTaskExactLogsService,
BoardTaskLogStreamService,
BranchStatusService,
ChangeExtractorService,
CliInstallerService,
FileContentResolver,

View file

@ -22,17 +22,17 @@ import {
TEAM_GET_DATA,
TEAM_GET_DELETED_TASKS,
TEAM_GET_LOGS_FOR_TASK,
TEAM_GET_TASK_ACTIVITY,
TEAM_GET_TASK_LOG_STREAM,
TEAM_GET_TASK_EXACT_LOG_DETAIL,
TEAM_GET_TASK_EXACT_LOG_SUMMARIES,
TEAM_GET_MEMBER_LOGS,
TEAM_GET_MEMBER_STATS,
TEAM_GET_MESSAGES_PAGE,
TEAM_GET_PROJECT_BRANCH,
TEAM_GET_SAVED_REQUEST,
TEAM_GET_TASK_ACTIVITY,
TEAM_GET_TASK_ATTACHMENT,
TEAM_GET_TASK_CHANGE_PRESENCE,
TEAM_GET_TASK_EXACT_LOG_DETAIL,
TEAM_GET_TASK_EXACT_LOG_SUMMARIES,
TEAM_GET_TASK_LOG_STREAM,
TEAM_KILL_PROCESS,
TEAM_LAUNCH,
TEAM_LEAD_ACTIVITY,
@ -121,11 +121,11 @@ import {
} from './guards';
import type {
BranchStatusService,
BoardTaskActivityService,
BoardTaskLogStreamService,
BoardTaskExactLogDetailService,
BoardTaskExactLogsService,
BoardTaskLogStreamService,
BranchStatusService,
MemberStatsComputer,
TeamDataService,
TeammateToolTracker,
@ -140,9 +140,9 @@ import type {
AttachmentMeta,
AttachmentPayload,
BoardTaskActivityEntry,
BoardTaskLogStreamResponse,
BoardTaskExactLogDetailResult,
BoardTaskExactLogSummariesResponse,
BoardTaskLogStreamResponse,
CreateTaskRequest,
EffortLevel,
GlobalTask,

View file

@ -7,13 +7,13 @@ import * as fs from 'fs/promises';
import * as path from 'path';
import * as readline from 'readline';
import { TeamConfigReader } from './TeamConfigReader';
import { TeamInboxReader } from './TeamInboxReader';
import { TeamMembersMetaStore } from './TeamMembersMetaStore';
import {
canonicalizeAgentTeamsToolName,
lineHasAgentTeamsTaskBoundaryToolName,
} from './agentTeamsToolNames';
import { TeamConfigReader } from './TeamConfigReader';
import { TeamInboxReader } from './TeamInboxReader';
import { TeamMembersMetaStore } from './TeamMembersMetaStore';
import type { MemberLogSummary, MemberSubagentLogSummary } from '@shared/types';

View file

@ -1,9 +1,4 @@
export { BranchStatusService } from './BranchStatusService';
export { BoardTaskActivityRecordSource } from './taskLogs/activity/BoardTaskActivityRecordSource';
export { BoardTaskActivityService } from './taskLogs/activity/BoardTaskActivityService';
export { BoardTaskExactLogsService } from './taskLogs/exact/BoardTaskExactLogsService';
export { BoardTaskExactLogDetailService } from './taskLogs/exact/BoardTaskExactLogDetailService';
export { BoardTaskLogStreamService } from './taskLogs/stream/BoardTaskLogStreamService';
export { CascadeGuard } from './CascadeGuard';
export { ChangeExtractorService } from './ChangeExtractorService';
export { ClaudeBinaryResolver } from './ClaudeBinaryResolver';
@ -15,6 +10,11 @@ export { HunkSnippetMatcher } from './HunkSnippetMatcher';
export { MemberStatsComputer } from './MemberStatsComputer';
export { ReviewApplierService } from './ReviewApplierService';
export { TaskBoundaryParser } from './TaskBoundaryParser';
export { BoardTaskActivityRecordSource } from './taskLogs/activity/BoardTaskActivityRecordSource';
export { BoardTaskActivityService } from './taskLogs/activity/BoardTaskActivityService';
export { BoardTaskExactLogDetailService } from './taskLogs/exact/BoardTaskExactLogDetailService';
export { BoardTaskExactLogsService } from './taskLogs/exact/BoardTaskExactLogsService';
export { BoardTaskLogStreamService } from './taskLogs/stream/BoardTaskLogStreamService';
export { TeamAttachmentStore } from './TeamAttachmentStore';
export { TeamBackupService } from './TeamBackupService';
export { TeamConfigReader } from './TeamConfigReader';

View file

@ -1,8 +1,8 @@
import { BoardTaskActivityRecordBuilder } from './BoardTaskActivityRecordBuilder';
import type { BoardTaskActivityEntry, TeamTask } from '@shared/types';
import type { RawTaskActivityMessage } from './BoardTaskActivityTranscriptReader';
import type { BoardTaskActivityRecord } from './BoardTaskActivityRecord';
import type { RawTaskActivityMessage } from './BoardTaskActivityTranscriptReader';
import type { BoardTaskActivityEntry, TeamTask } from '@shared/types';
function cloneTaskRef(task: BoardTaskActivityRecord['task']): BoardTaskActivityEntry['task'] {
return {

View file

@ -1,6 +1,12 @@
import { createLogger } from '@shared/utils/logger';
import { getTaskDisplayId } from '@shared/utils/taskIdentity';
import type {
ParsedBoardTaskLink,
ParsedBoardTaskToolAction,
} from '../contract/BoardTaskTranscriptContract';
import type { BoardTaskActivityRecord } from './BoardTaskActivityRecord';
import type { RawTaskActivityMessage } from './BoardTaskActivityTranscriptReader';
import type {
BoardTaskActivityAction,
BoardTaskActivityActor,
@ -10,12 +16,6 @@ import type {
TaskRef,
TeamTask,
} from '@shared/types';
import type { RawTaskActivityMessage } from './BoardTaskActivityTranscriptReader';
import type {
ParsedBoardTaskLink,
ParsedBoardTaskToolAction,
} from '../contract/BoardTaskTranscriptContract';
import type { BoardTaskActivityRecord } from './BoardTaskActivityRecord';
interface TaskLookup {
byId: Map<string, TeamTask>;

View file

@ -1,5 +1,6 @@
import { TeamTaskReader } from '../../TeamTaskReader';
import { TeamTranscriptSourceLocator } from '../discovery/TeamTranscriptSourceLocator';
import { BoardTaskActivityRecordBuilder } from './BoardTaskActivityRecordBuilder';
import { BoardTaskActivityTranscriptReader } from './BoardTaskActivityTranscriptReader';

View file

@ -1,11 +1,9 @@
import { yieldToEventLoop } from '@main/utils/asyncYield';
import { createLogger } from '@shared/utils/logger';
import { createReadStream } from 'fs';
import * as fs from 'fs/promises';
import * as readline from 'readline';
import { yieldToEventLoop } from '@main/utils/asyncYield';
import { BoardTaskActivityParseCache } from './BoardTaskActivityParseCache';
import {
parseBoardTaskLinks,
parseBoardTaskToolActions,
@ -13,6 +11,8 @@ import {
type ParsedBoardTaskToolAction,
} from '../contract/BoardTaskTranscriptContract';
import { BoardTaskActivityParseCache } from './BoardTaskActivityParseCache';
const logger = createLogger('Service:BoardTaskActivityTranscriptReader');
export interface RawTaskActivityMessage {

View file

@ -1,4 +1,5 @@
import { createLogger } from '@shared/utils/logger';
import type {
BoardTaskActivityLinkKind,
BoardTaskActivityPhase,

View file

@ -1,13 +1,14 @@
import { getTaskDisplayId, taskMatchesRef } from '@shared/utils/taskIdentity';
import { TeamTaskReader } from '../../TeamTaskReader';
import { BoardTaskActivityRecordSource } from '../activity/BoardTaskActivityRecordSource';
import type { BoardTaskActivityRecord } from '../activity/BoardTaskActivityRecord';
import { TeamTranscriptSourceLocator } from '../discovery/TeamTranscriptSourceLocator';
import { BoardTaskExactLogStrictParser } from '../exact/BoardTaskExactLogStrictParser';
import { BoardTaskLogStreamService } from '../stream/BoardTaskLogStreamService';
import type { BoardTaskActivityRecord } from '../activity/BoardTaskActivityRecord';
import type { ParsedMessage } from '@main/types';
import type { TeamTask, TaskWorkInterval } from '@shared/types';
import { getTaskDisplayId, taskMatchesRef } from '@shared/utils/taskIdentity';
import type { TaskWorkInterval, TeamTask } from '@shared/types';
const BOARD_MCP_TOOL_PREFIXES = ['mcp__agent-teams__', 'mcp__agent_teams__'] as const;
const MAX_EXAMPLES = 10;

View file

@ -1,12 +1,12 @@
import { extractToolCalls, extractToolResults } from '@main/utils/toolExtraction';
import { createLogger } from '@shared/utils/logger';
import type { ContentBlock, ParsedMessage } from '@main/types';
import type { BoardTaskActivityRecord } from '../activity/BoardTaskActivityRecord';
import type {
BoardTaskExactLogDetailCandidate,
BoardTaskExactLogBundleCandidate,
BoardTaskExactLogDetailCandidate,
} from './BoardTaskExactLogTypes';
import type { ContentBlock, ParsedMessage } from '@main/types';
const logger = createLogger('Service:BoardTaskExactLogDetailSelector');
@ -63,7 +63,7 @@ function cloneBlock<T extends ContentBlock>(block: T): T {
} as T;
}
return { ...block } as T;
return { ...block };
}
function filterAssistantContent(
@ -249,7 +249,7 @@ function deduplicateAssistantMessagesByRequestId(
continue;
}
const existingRank = anchorEvidenceRank(messages[existingIndex]!, toolUseId);
const existingRank = anchorEvidenceRank(messages[existingIndex], toolUseId);
const nextRank = anchorEvidenceRank(message, toolUseId);
if (nextRank > existingRank || (nextRank === existingRank && i > existingIndex)) {
preferredAssistantIndexByRequestId.set(message.requestId, i);

View file

@ -1,10 +1,11 @@
import { BoardTaskActivityRecordSource } from '../activity/BoardTaskActivityRecordSource';
import { BoardTaskExactLogChunkBuilder } from './BoardTaskExactLogChunkBuilder';
import { BoardTaskExactLogDetailSelector } from './BoardTaskExactLogDetailSelector';
import { BoardTaskExactLogStrictParser } from './BoardTaskExactLogStrictParser';
import { BoardTaskExactLogSummarySelector } from './BoardTaskExactLogSummarySelector';
import { isBoardTaskExactLogsReadEnabled } from './featureGates';
import { getBoardTaskExactLogFileVersions } from './fileVersions';
import { BoardTaskExactLogSummarySelector } from './BoardTaskExactLogSummarySelector';
import type { BoardTaskExactLogDetailResult } from '@shared/types';

View file

@ -1,11 +1,10 @@
import { yieldToEventLoop } from '@main/utils/asyncYield';
import { parseJsonlLine } from '@main/utils/jsonl';
import { createLogger } from '@shared/utils/logger';
import { createReadStream } from 'fs';
import * as fs from 'fs/promises';
import * as readline from 'readline';
import { yieldToEventLoop } from '@main/utils/asyncYield';
import { parseJsonlLine } from '@main/utils/jsonl';
import { BoardTaskExactLogsParseCache } from './BoardTaskExactLogsParseCache';
import type { ParsedMessage } from '@main/types';

View file

@ -1,7 +1,6 @@
import { createHash } from 'crypto';
import { describeBoardTaskActivityLabel } from '@shared/utils/boardTaskActivityLabels';
import { createLogger } from '@shared/utils/logger';
import { createHash } from 'crypto';
import type { BoardTaskActivityRecord } from '../activity/BoardTaskActivityRecord';
import type {
@ -75,7 +74,7 @@ function sourceGenerationFor(
version: BoardTaskExactLogFileVersion | undefined
): string | null {
if (!version) return null;
const hash = createHash('sha1');
const hash = createHash('sha256');
hash.update(anchor.filePath);
hash.update('\0');
hash.update(String(version.size));

View file

@ -1,3 +1,4 @@
import type { BoardTaskActivityRecord } from '../activity/BoardTaskActivityRecord';
import type { ParsedMessage } from '@main/types';
import type {
BoardTaskActivityCategory,
@ -7,7 +8,6 @@ import type {
BoardTaskExactLogSource,
BoardTaskExactLogSummary,
} from '@shared/types';
import type { BoardTaskActivityRecord } from '../activity/BoardTaskActivityRecord';
export interface BoardTaskExactLogFileVersion {
filePath: string;

View file

@ -1,8 +1,9 @@
import { BoardTaskActivityRecordSource } from '../activity/BoardTaskActivityRecordSource';
import { isBoardTaskExactLogsReadEnabled } from './featureGates';
import { getBoardTaskExactLogFileVersions } from './fileVersions';
import { BoardTaskExactLogSummarySelector } from './BoardTaskExactLogSummarySelector';
import { mapCandidateToSummary } from './BoardTaskExactLogTypes';
import { isBoardTaskExactLogsReadEnabled } from './featureGates';
import { getBoardTaskExactLogFileVersions } from './fileVersions';
import type { BoardTaskExactLogSummariesResponse } from '@shared/types';

View file

@ -4,10 +4,11 @@ import { BoardTaskActivityRecordSource } from '../activity/BoardTaskActivityReco
import { BoardTaskExactLogChunkBuilder } from '../exact/BoardTaskExactLogChunkBuilder';
import { BoardTaskExactLogDetailSelector } from '../exact/BoardTaskExactLogDetailSelector';
import { BoardTaskExactLogStrictParser } from '../exact/BoardTaskExactLogStrictParser';
import { BoardTaskExactLogSummarySelector } from '../exact/BoardTaskExactLogSummarySelector';
import { isBoardTaskExactLogsReadEnabled } from '../exact/featureGates';
import { getBoardTaskExactLogFileVersions } from '../exact/fileVersions';
import { BoardTaskExactLogSummarySelector } from '../exact/BoardTaskExactLogSummarySelector';
import type { BoardTaskExactLogDetailCandidate } from '../exact/BoardTaskExactLogTypes';
import type { ContentBlock, ParsedMessage, ToolUseResultData } from '@main/types';
import type {
BoardTaskActivityCategory,
@ -16,7 +17,6 @@ import type {
BoardTaskLogSegment,
BoardTaskLogStreamResponse,
} from '@shared/types';
import type { BoardTaskExactLogDetailCandidate } from '../exact/BoardTaskExactLogTypes';
interface StreamSlice {
id: string;
@ -533,7 +533,7 @@ function cloneBlock<T extends ContentBlock>(block: T): T {
} as T;
}
return { ...block } as T;
return { ...block };
}
function cloneMessageContent(content: ParsedMessage['content']): ParsedMessage['content'] {
@ -655,7 +655,7 @@ function rebuildMergedMessage(
}
function mergeMessages(
details: Array<{ filePath: string; filteredMessages: ParsedMessage[] }>
details: { filePath: string; filteredMessages: ParsedMessage[] }[]
): ParsedMessage[] {
const byMessageKey = new Map<string, MergedMessageAccumulator>();
let order = 0;
@ -808,8 +808,8 @@ export class BoardTaskLogStreamService {
const flushSegment = (): void => {
if (currentSegmentSlices.length === 0) return;
const participantKey = currentSegmentSlices[0]!.participantKey;
const actor = currentSegmentSlices[0]!.actor;
const participantKey = currentSegmentSlices[0].participantKey;
const actor = currentSegmentSlices[0].actor;
const mergedMessages = mergeMessages(
currentSegmentSlices.map((slice) => ({
filePath: slice.filePath,
@ -827,8 +827,8 @@ export class BoardTaskLogStreamService {
id: buildSegmentId(participantKey, currentSegmentSlices),
participantKey,
actor,
startTimestamp: currentSegmentSlices[0]!.timestamp,
endTimestamp: currentSegmentSlices[currentSegmentSlices.length - 1]!.timestamp,
startTimestamp: currentSegmentSlices[0].timestamp,
endTimestamp: currentSegmentSlices[currentSegmentSlices.length - 1].timestamp,
chunks,
});
}
@ -838,7 +838,7 @@ export class BoardTaskLogStreamService {
for (const slice of visibleSlices) {
if (
currentSegmentSlices.length > 0 &&
currentSegmentSlices[0]!.participantKey !== slice.participantKey
currentSegmentSlices[0].participantKey !== slice.participantKey
) {
flushSegment();
}
@ -847,7 +847,7 @@ export class BoardTaskLogStreamService {
flushSegment();
const namedParticipants = orderedParticipants.filter((participant) => !participant.isLead);
const defaultFilter = namedParticipants.length === 1 ? namedParticipants[0]!.key : 'all';
const defaultFilter = namedParticipants.length === 1 ? namedParticipants[0].key : 'all';
return {
participants: orderedParticipants,

View file

@ -124,17 +124,17 @@ import {
TEAM_GET_DATA,
TEAM_GET_DELETED_TASKS,
TEAM_GET_LOGS_FOR_TASK,
TEAM_GET_TASK_ACTIVITY,
TEAM_GET_TASK_LOG_STREAM,
TEAM_GET_TASK_EXACT_LOG_DETAIL,
TEAM_GET_TASK_EXACT_LOG_SUMMARIES,
TEAM_GET_MEMBER_LOGS,
TEAM_GET_MEMBER_STATS,
TEAM_GET_MESSAGES_PAGE,
TEAM_GET_PROJECT_BRANCH,
TEAM_GET_SAVED_REQUEST,
TEAM_GET_TASK_ACTIVITY,
TEAM_GET_TASK_ATTACHMENT,
TEAM_GET_TASK_CHANGE_PRESENCE,
TEAM_GET_TASK_EXACT_LOG_DETAIL,
TEAM_GET_TASK_EXACT_LOG_SUMMARIES,
TEAM_GET_TASK_LOG_STREAM,
TEAM_KILL_PROCESS,
TEAM_LAUNCH,
TEAM_LEAD_ACTIVITY,
@ -233,9 +233,9 @@ import type {
ApplyReviewResult,
AttachmentFileData,
BoardTaskActivityEntry,
BoardTaskLogStreamResponse,
BoardTaskExactLogDetailResult,
BoardTaskExactLogSummariesResponse,
BoardTaskLogStreamResponse,
ChangeStats,
ClaudeRootFolderSelection,
ClaudeRootInfo,

View file

@ -9,9 +9,9 @@
import type {
AppConfig,
AttachmentFileData,
BoardTaskLogStreamResponse,
BoardTaskExactLogDetailResult,
BoardTaskExactLogSummariesResponse,
BoardTaskLogStreamResponse,
ClaudeMdFileInfo,
ClaudeRootFolderSelection,
ClaudeRootInfo,

View file

@ -1,7 +1,7 @@
import { useEffect, useMemo, useState } from 'react';
import { Button } from '@renderer/components/ui/button';
import { ProviderBrandLogo } from '@renderer/components/common/ProviderBrandLogo';
import { Button } from '@renderer/components/ui/button';
import {
Dialog,
DialogContent,
@ -1059,7 +1059,7 @@ export const ProviderRuntimeSettingsDialog = ({
) : null}
</div>
{showApiKeySection ? (
{showApiKeySection && apiKeyConfig ? (
<div
className="space-y-3 rounded-md border p-3"
style={{ borderColor: 'var(--color-border-subtle)' }}
@ -1069,7 +1069,7 @@ export const ProviderRuntimeSettingsDialog = ({
<div className="flex items-center gap-2">
<div
data-testid="provider-api-key-icon"
className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md border"
className="flex size-8 shrink-0 items-center justify-center rounded-md border"
style={{
borderColor: 'var(--color-border-subtle)',
backgroundColor: 'rgba(255,255,255,0.03)',

View file

@ -71,8 +71,8 @@ import { KanbanSearchInput } from './kanban/KanbanSearchInput';
import { TrashDialog } from './kanban/TrashDialog';
import { MemberDetailDialog } from './members/MemberDetailDialog';
import type { TeamMessagesPanelMode } from '@renderer/types/teamMessagesPanelMode';
import type { AddMemberEntry } from './dialogs/AddMemberDialog';
import type { TeamMessagesPanelMode } from '@renderer/types/teamMessagesPanelMode';
import type { ComponentProps } from 'react';
const ProjectEditorOverlay = lazy(() =>

View file

@ -1,4 +1,4 @@
import { useState, type ReactNode } from 'react';
import { type ReactNode, useState } from 'react';
import { CARD_BG, CARD_BORDER_STYLE, CARD_ICON_MUTED } from '@renderer/constants/cssVariables';
import { getTeamColorSet, getThemedBadge } from '@renderer/constants/teamColors';

View file

@ -41,8 +41,8 @@ import {
normalizeCreateLaunchProviderForUi,
} from '@renderer/utils/geminiUiFreeze';
import { normalizePath } from '@renderer/utils/pathNormalize';
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
import { AlertTriangle, CheckCircle2, Info, Loader2, X } from 'lucide-react';

View file

@ -43,8 +43,8 @@ import {
} from '@renderer/utils/geminiUiFreeze';
import { normalizePath } from '@renderer/utils/pathNormalize';
import { nameColorSet } from '@renderer/utils/projectColor';
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
import { normalizeTeamModelForUi } from '@renderer/utils/teamModelAvailability';
import { getTeamProviderLabel as getCatalogTeamProviderLabel } from '@renderer/utils/teamModelCatalog';
import { isTeamProviderId, normalizeOptionalTeamProviderId } from '@shared/utils/teamProvider';
import {
AlertTriangle,

View file

@ -159,7 +159,7 @@ function estimateGridSkeletonCardHeight(
if ((task.blockedBy?.length ?? 0) > 0) height += 18;
if ((task.blocks?.length ?? 0) > 0) height += 18;
const effectiveReviewer = (kanbanState.tasks[task.id]?.reviewer ?? task.reviewer ?? '').trim();
const effectiveReviewer = (kanbanState.tasks[task.id]?.reviewer ?? '').trim();
if (columnId === 'review' && !hasReviewers && effectiveReviewer.length === 0) {
height += 14;
}

View file

@ -39,10 +39,10 @@ export interface KanbanGridColumn {
bodyBg?: string;
content: React.ReactNode;
showAddButton?: boolean;
skeletonCards?: Array<{
skeletonCards?: {
key: string;
height: number;
}>;
}[];
}
interface KanbanGridLayoutProps {

View file

@ -298,7 +298,7 @@ export const MessagesPanel = memo(function MessagesPanel({
if (position !== 'bottom-sheet' || typeof ResizeObserver === 'undefined') return;
const mountPointElement = mountPoint instanceof HTMLElement ? mountPoint : null;
const observedEntries: Array<[Element | null, (height: number) => void]> = [
const observedEntries: [Element | null, (height: number) => void][] = [
[bottomSheetStickyTopRef.current, setBottomSheetStickyTopHeight],
[mountPointElement, setBottomSheetMountHeight],
];
@ -1096,7 +1096,7 @@ export const MessagesPanel = memo(function MessagesPanel({
{searchAndFilterControls}
</div>
)}
<div className="px-3 pb-3 pt-3">
<div className="p-3">
<MessageComposer
teamName={teamName}
layout="compact"

View file

@ -1,7 +1,7 @@
import { MemberExecutionLog } from '@renderer/components/team/members/MemberExecutionLog';
import { asEnhancedChunkArray } from '@renderer/types/data';
import { ChevronDown, ChevronRight, Clock, FileText, Loader2 } from 'lucide-react';
import type { asEnhancedChunkArray } from '@renderer/types/data';
import type { BoardTaskExactLogSummary } from '@shared/types';
export interface ExactTaskLogDetailState {
@ -61,12 +61,12 @@ interface ExactTaskLogCardProps {
onToggle: () => void;
}
export function ExactTaskLogCard({
export const ExactTaskLogCard = ({
summary,
expanded,
detailState,
onToggle,
}: ExactTaskLogCardProps): React.JSX.Element {
}: ExactTaskLogCardProps): React.JSX.Element => {
const loadStateText = describeDetailState(detailState);
return (
@ -129,4 +129,4 @@ export function ExactTaskLogCard({
) : null}
</div>
);
}
};

View file

@ -13,10 +13,10 @@ interface ExactTaskLogsSectionProps {
taskId: string;
}
export function ExactTaskLogsSection({
export const ExactTaskLogsSection = ({
teamName,
taskId,
}: ExactTaskLogsSectionProps): React.JSX.Element {
}: ExactTaskLogsSectionProps): React.JSX.Element => {
const [summaries, setSummaries] = useState<BoardTaskExactLogSummary[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@ -259,4 +259,4 @@ export function ExactTaskLogsSection({
)}
</div>
);
}
};

View file

@ -1,18 +1,18 @@
import type { ComponentProps } from 'react';
import { MemberLogsTab } from '@renderer/components/team/members/MemberLogsTab';
import { Loader2 } from 'lucide-react';
import type { ComponentProps } from 'react';
interface ExecutionSessionsSectionProps extends ComponentProps<typeof MemberLogsTab> {
isRefreshing?: boolean;
isPreviewOnline?: boolean;
}
export function ExecutionSessionsSection({
export const ExecutionSessionsSection = ({
isRefreshing = false,
isPreviewOnline = false,
...props
}: ExecutionSessionsSectionProps): React.JSX.Element {
}: ExecutionSessionsSectionProps): React.JSX.Element => {
return (
<div className="space-y-2">
<div className="flex items-center gap-2">
@ -45,4 +45,4 @@ export function ExecutionSessionsSection({
<MemberLogsTab {...props} />
</div>
);
}
};

View file

@ -1,10 +1,11 @@
import { api } from '@renderer/api';
import { AlertCircle, Loader2 } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { api } from '@renderer/api';
import {
describeBoardTaskActivityLabel,
formatBoardTaskActivityTaskLabel,
} from '@shared/utils/boardTaskActivityLabels';
import { AlertCircle, Loader2 } from 'lucide-react';
import type { BoardTaskActivityEntry, BoardTaskActivityTaskRef } from '@shared/types';
@ -84,7 +85,7 @@ function actorLabel(entry: BoardTaskActivityEntry): string {
return 'unknown actor';
}
function Row({ entry }: { entry: BoardTaskActivityEntry }): React.JSX.Element {
const Row = ({ entry }: { entry: BoardTaskActivityEntry }): React.JSX.Element => {
const context = describeContext(entry);
const tone =
entry.task.resolution === 'resolved'
@ -110,12 +111,12 @@ function Row({ entry }: { entry: BoardTaskActivityEntry }): React.JSX.Element {
</div>
</div>
);
}
};
export function TaskActivitySection({
export const TaskActivitySection = ({
teamName,
taskId,
}: TaskActivitySectionProps): React.JSX.Element {
}: TaskActivitySectionProps): React.JSX.Element => {
const [entries, setEntries] = useState<BoardTaskActivityEntry[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@ -208,4 +209,4 @@ export function TaskActivitySection({
{content}
</div>
);
}
};

View file

@ -54,7 +54,7 @@ function normalizeResponse(response: BoardTaskLogStreamResponse): BoardTaskLogSt
};
}
function SegmentMarker({ segment }: { segment: BoardTaskLogSegment }): React.JSX.Element {
const SegmentMarker = ({ segment }: { segment: BoardTaskLogSegment }): React.JSX.Element => {
return (
<div className="mb-2 flex items-center gap-2 text-[10px] text-[var(--color-text-muted)]">
<span className="rounded-full border border-[var(--color-border)] px-2 py-0.5 font-medium text-[var(--color-text-secondary)]">
@ -66,27 +66,27 @@ function SegmentMarker({ segment }: { segment: BoardTaskLogSegment }): React.JSX
</span>
</div>
);
}
};
function SegmentBlock({
const SegmentBlock = ({
segment,
showHeader,
}: {
segment: BoardTaskLogSegment;
showHeader: boolean;
}): React.JSX.Element {
}): React.JSX.Element => {
return (
<div className="min-w-0 overflow-hidden">
{showHeader ? <SegmentMarker segment={segment} /> : null}
<MemberExecutionLog chunks={segment.chunks} memberName={segment.actor.memberName} />
</div>
);
}
};
export function TaskLogStreamSection({
export const TaskLogStreamSection = ({
teamName,
taskId,
}: TaskLogStreamSectionProps): React.JSX.Element {
}: TaskLogStreamSectionProps): React.JSX.Element => {
const [stream, setStream] = useState<BoardTaskLogStreamResponse | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@ -219,4 +219,4 @@ export function TaskLogStreamSection({
)}
</div>
);
}
};

View file

@ -1,7 +1,7 @@
import { ExecutionSessionsSection } from './ExecutionSessionsSection';
import { isBoardTaskActivityUiEnabled, isBoardTaskExactLogsUiEnabled } from './featureGates';
import { TaskActivitySection } from './TaskActivitySection';
import { TaskLogStreamSection } from './TaskLogStreamSection';
import { isBoardTaskActivityUiEnabled, isBoardTaskExactLogsUiEnabled } from './featureGates';
import type { TeamTaskWithKanban } from '@shared/types';
@ -17,7 +17,7 @@ interface TaskLogsPanelProps {
onPreviewOnlineChange?: (isOnline: boolean) => void;
}
export function TaskLogsPanel({
export const TaskLogsPanel = ({
teamName,
task,
taskSince,
@ -27,7 +27,7 @@ export function TaskLogsPanel({
showSubagentPreview = false,
showLeadPreview = false,
onPreviewOnlineChange,
}: TaskLogsPanelProps): React.JSX.Element {
}: TaskLogsPanelProps): React.JSX.Element => {
return (
<div className="space-y-4">
{isBoardTaskActivityUiEnabled() ? (
@ -52,4 +52,4 @@ export function TaskLogsPanel({
/>
</div>
);
}
};

View file

@ -2,8 +2,8 @@ import { useMemo } from 'react';
import { useStore } from '@renderer/store';
import {
selectTeamDataForName,
getCurrentProvisioningProgressForTeam,
selectTeamDataForName,
} from '@renderer/store/slices/teamSlice';
import { buildTeamProvisioningPresentation } from '@renderer/utils/teamProvisioningPresentation';
import { useShallow } from 'zustand/react/shallow';

View file

@ -1134,7 +1134,7 @@ export const MentionableTextarea = React.forwardRef<HTMLTextAreaElement, Mention
surfaceShellMetrics.width > 0 &&
surfaceShellMetrics.height > 0 ? (
<svg
className="message-composer-orbit-svg pointer-events-none absolute inset-0 z-[16] h-full w-full"
className="message-composer-orbit-svg pointer-events-none absolute inset-0 z-[16] size-full"
viewBox={`0 0 ${surfaceShellMetrics.width} ${surfaceShellMetrics.height}`}
aria-hidden="true"
>

View file

@ -23,11 +23,11 @@ import {
import { isInboxNoiseMessage } from '@shared/utils/inboxNoise';
import { isLeadMember } from '@shared/utils/leadDetection';
import { collapseOverflowStacksWithMeta } from '../utils/collapseOverflowStacks';
import {
buildInlineActivityEntries,
getGraphLeadMemberName,
} from '../utils/buildInlineActivityEntries';
import { collapseOverflowStacksWithMeta } from '../utils/collapseOverflowStacks';
import {
isTaskBlocked,
isTaskInReviewCycle,
@ -35,8 +35,8 @@ import {
} from '../utils/taskGraphSemantics';
import type {
GraphDataPort,
GraphActivityItem,
GraphDataPort,
GraphEdge,
GraphNode,
GraphNodeState,
@ -48,8 +48,8 @@ import type {
LeadActivityState,
MemberSpawnStatusEntry,
MemberSpawnStatusesSnapshot,
TeamProvisioningProgress,
TeamData,
TeamProvisioningProgress,
} from '@shared/types/team';
import type { LeadContextUsage } from '@shared/types/team';

View file

@ -6,8 +6,8 @@ import {
resolveMessageRenderProps,
} from '@renderer/components/team/activity/activityMessageContext';
import { MessageExpandDialog } from '@renderer/components/team/activity/MessageExpandDialog';
import { useTeamMessagesRead } from '@renderer/hooks/useTeamMessagesRead';
import { useStableTeamMentionMeta } from '@renderer/hooks/useStableTeamMentionMeta';
import { useTeamMessagesRead } from '@renderer/hooks/useTeamMessagesRead';
import { useStore } from '@renderer/store';
import { selectTeamDataForName } from '@renderer/store/slices/teamSlice';
import { toMessageKey } from '@renderer/utils/teamMessageKey';
@ -19,8 +19,8 @@ import {
type InlineActivityEntry,
} from '../utils/buildInlineActivityEntries';
import type { TimelineItem } from '@renderer/components/team/activity/LeadThoughtsGroup';
import type { GraphNode } from '@claude-teams/agent-graph';
import type { TimelineItem } from '@renderer/components/team/activity/LeadThoughtsGroup';
import type { ResolvedTeamMember } from '@shared/types/team';
interface GraphActivityHudProps {
@ -35,7 +35,7 @@ interface GraphActivityHudProps {
onOpenMemberProfile?: (memberName: string) => void;
}
export function GraphActivityHud({
export const GraphActivityHud = ({
teamName,
nodes,
getActivityAnchorScreenPlacement,
@ -43,7 +43,7 @@ export function GraphActivityHud({
enabled = true,
onOpenTaskDetail,
onOpenMemberProfile,
}: GraphActivityHudProps): React.JSX.Element | null {
}: GraphActivityHudProps): React.JSX.Element | null => {
const shellRefs = useRef(new Map<string, HTMLDivElement | null>());
const [expandedItem, setExpandedItem] = useState<TimelineItem | null>(null);
const { teamData, teams } = useStore(
@ -128,7 +128,7 @@ export function GraphActivityHud({
}
const placement = getActivityAnchorScreenPlacement(lane.node.id);
if (!placement || !placement.visible) {
if (!placement?.visible) {
shell.style.opacity = '0';
continue;
}
@ -275,4 +275,4 @@ export function GraphActivityHud({
/>
</>
);
}
};

View file

@ -54,7 +54,7 @@ export interface GraphBlockingEdgePopoverProps {
onOpenTaskDetail?: (taskId: string) => void;
}
export function GraphBlockingEdgePopover({
export const GraphBlockingEdgePopover = ({
teamName,
edge,
sourceNode,
@ -62,7 +62,7 @@ export function GraphBlockingEdgePopover({
onClose,
onSelectNode,
onOpenTaskDetail,
}: GraphBlockingEdgePopoverProps): React.JSX.Element {
}: GraphBlockingEdgePopoverProps): React.JSX.Element => {
const teamData = useStore((state) => selectTeamDataForName(state, teamName));
const tasksById = useMemo(
() => new Map((teamData?.tasks ?? []).map((task) => [task.id, task] as const)),
@ -153,7 +153,7 @@ export function GraphBlockingEdgePopover({
</div>
</div>
);
}
};
function resolveEdgeTaskPreview(
node: GraphNode | undefined,
@ -173,7 +173,7 @@ function resolveEdgeTaskPreview(
.slice(0, 4);
}
function HiddenTaskPreview({
const HiddenTaskPreview = ({
title,
tasks,
onOpenTaskDetail,
@ -183,10 +183,10 @@ function HiddenTaskPreview({
tasks: TeamTaskWithKanban[];
onOpenTaskDetail?: (taskId: string) => void;
onClose: () => void;
}): React.JSX.Element {
}): React.JSX.Element => {
return (
<div className="mt-2 rounded border border-red-500/15 bg-red-500/5 px-2 py-2">
<div className="text-[10px] uppercase tracking-[0.1em] text-red-300/80">{title}</div>
<div className="mt-2 rounded border border-red-500/15 bg-red-500/5 p-2">
<div className="text-[10px] uppercase tracking-widest text-red-300/80">{title}</div>
<div className="mt-1 space-y-1">
{tasks.map((task) => (
<button
@ -204,4 +204,4 @@ function HiddenTaskPreview({
</div>
</div>
);
}
};

View file

@ -17,6 +17,7 @@ import { ExternalLink, Loader2, MessageSquare, Plus, User } from 'lucide-react';
import { useShallow } from 'zustand/react/shallow';
import { isTaskInReviewCycle, resolveTaskReviewer } from '../utils/taskGraphSemantics';
import { GraphTaskCard } from './GraphTaskCard';
import type { GraphNode } from '@claude-teams/agent-graph';
@ -225,7 +226,7 @@ const OverflowPopoverContent = ({
<button
key={task.id}
type="button"
className="flex w-full items-start justify-between gap-2 rounded border border-[var(--color-border)] bg-[var(--color-surface-secondary)] px-2 py-2 text-left transition-colors hover:border-[var(--color-border-emphasis)]"
className="flex w-full items-start justify-between gap-2 rounded border border-[var(--color-border)] bg-[var(--color-surface-secondary)] p-2 text-left transition-colors hover:border-[var(--color-border-emphasis)]"
onClick={() => {
onOpenTaskDetail?.(task.id);
onClose();

View file

@ -1,5 +1,9 @@
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { DISPLAY_STEPS } from '@renderer/components/team/provisioningSteps';
import { StepProgressBar } from '@renderer/components/team/StepProgressBar';
import { TeamProvisioningPanel } from '@renderer/components/team/TeamProvisioningPanel';
import { useTeamProvisioningPresentation } from '@renderer/components/team/useTeamProvisioningPresentation';
import { Badge } from '@renderer/components/ui/badge';
import {
Dialog,
@ -8,10 +12,6 @@ import {
DialogHeader,
DialogTitle,
} from '@renderer/components/ui/dialog';
import { TeamProvisioningPanel } from '@renderer/components/team/TeamProvisioningPanel';
import { StepProgressBar } from '@renderer/components/team/StepProgressBar';
import { useTeamProvisioningPresentation } from '@renderer/components/team/useTeamProvisioningPresentation';
import { DISPLAY_STEPS } from '@renderer/components/team/provisioningSteps';
import { cn } from '@renderer/lib/utils';
import { AlertTriangle, CheckCircle2, ExternalLink, Loader2, X } from 'lucide-react';
@ -87,12 +87,12 @@ export interface GraphProvisioningHudProps {
enabled?: boolean;
}
export function GraphProvisioningHud({
export const GraphProvisioningHud = ({
teamName,
leadNodeId,
getLaunchAnchorScreenPlacement,
enabled = true,
}: GraphProvisioningHudProps): React.JSX.Element | null {
}: GraphProvisioningHudProps): React.JSX.Element | null => {
const { presentation, runInstanceKey } = useTeamProvisioningPresentation(teamName);
const shellRef = useRef<HTMLDivElement>(null);
const lastActiveStepRef = useRef(-1);
@ -180,7 +180,7 @@ export function GraphProvisioningHud({
>
<div
className={cn(
'rounded-xl border px-3 py-3 text-slate-100 shadow-[0_18px_48px_rgba(5,5,16,0.38)] backdrop-blur-xl',
'rounded-xl border p-3 text-slate-100 shadow-[0_18px_48px_rgba(5,5,16,0.38)] backdrop-blur-xl',
tone.border
)}
>
@ -227,7 +227,7 @@ export function GraphProvisioningHud({
<button
type="button"
className="border-cyan-300/12 mt-3 w-full rounded-xl border bg-[rgba(4,10,20,0.58)] px-3 py-3 text-left transition-colors hover:bg-[rgba(8,18,32,0.76)]"
className="border-cyan-300/12 mt-3 w-full rounded-xl border bg-[rgba(4,10,20,0.58)] p-3 text-left transition-colors hover:bg-[rgba(8,18,32,0.76)]"
style={HUD_STEPPER_STYLE}
onClick={() => setDetailsOpen(true)}
aria-label="Open full launch details"
@ -256,4 +256,4 @@ export function GraphProvisioningHud({
</Dialog>
</div>
);
}
};

View file

@ -10,8 +10,8 @@ import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHo
import { useTeamGraphAdapter } from '../adapters/useTeamGraphAdapter';
import { GraphBlockingEdgePopover } from './GraphBlockingEdgePopover';
import { GraphActivityHud } from './GraphActivityHud';
import { GraphBlockingEdgePopover } from './GraphBlockingEdgePopover';
import { GraphNodePopover } from './GraphNodePopover';
import { GraphProvisioningHud } from './GraphProvisioningHud';

View file

@ -10,8 +10,8 @@ import { TeamSidebarHost } from '@renderer/components/team/sidebar/TeamSidebarHo
import { useTeamGraphAdapter } from '../adapters/useTeamGraphAdapter';
import { GraphBlockingEdgePopover } from './GraphBlockingEdgePopover';
import { GraphActivityHud } from './GraphActivityHud';
import { GraphBlockingEdgePopover } from './GraphBlockingEdgePopover';
import { GraphNodePopover } from './GraphNodePopover';
import { GraphProvisioningHud } from './GraphProvisioningHud';

View file

@ -160,8 +160,8 @@ export function buildInlineActivityEntries({
function collectTaskComments(
tasks: readonly TeamTaskWithKanban[]
): Array<{ task: TeamTaskWithKanban; comment: TaskComment }> {
const items: Array<{ task: TeamTaskWithKanban; comment: TaskComment }> = [];
): { task: TeamTaskWithKanban; comment: TaskComment }[] {
const items: { task: TeamTaskWithKanban; comment: TaskComment }[] = [];
for (const task of tasks) {
for (const comment of task.comments ?? []) {
items.push({ task, comment });

View file

@ -1,4 +1,4 @@
import type { KanbanTaskState, KanbanColumnId, TeamTask, TeamTaskWithKanban } from '@shared/types';
import type { KanbanColumnId, KanbanTaskState, TeamTask, TeamTaskWithKanban } from '@shared/types';
type TaskColumnInput = Pick<TeamTaskWithKanban, 'status' | 'reviewState' | 'kanbanColumn'>;
type TaskReviewerInput = Pick<TeamTaskWithKanban, 'reviewer' | 'reviewState' | 'kanbanColumn'>;

View file

@ -195,7 +195,7 @@ export function initializeNotificationListeners(): () => void {
const nav: NavigatorWithUserAgentData | null =
typeof navigator !== 'undefined' ? (navigator as NavigatorWithUserAgentData) : null;
// Prefer UA-CH when available; fall back to deprecated-but-still-supported navigator.platform.
// eslint-disable-next-line sonarjs/deprecation -- navigator.platform is deprecated but needed as fallback
const platform: string =
nav?.userAgentData?.platform ?? nav?.platform ?? nav?.userAgent ?? '';
const isWindows = platform.toLowerCase().includes('win');

View file

@ -484,31 +484,31 @@ export function buildMemberLaunchPresentation({
const keepLaunchSettlingVisuals = isTeamProvisioning === true || isLaunchSettling;
let launchVisualState: MemberLaunchVisualState = null;
if (isTeamAlive === false && !isTeamProvisioning) {
launchVisualState = null;
} else if (spawnLaunchState === 'failed_to_start' || spawnStatus === 'error') {
launchVisualState = 'error';
} else if (
spawnLaunchState === 'runtime_pending_bootstrap' &&
spawnStatus === 'online' &&
spawnRuntimeAlive === true
) {
launchVisualState = 'runtime_pending';
} else if (
isLaunchStillStarting(
spawnStatus,
spawnLaunchState,
spawnRuntimeAlive,
keepLaunchSettlingVisuals
)
) {
launchVisualState = spawnStatus === 'spawning' ? 'spawning' : 'waiting';
} else if (
isLaunchSettling &&
spawnStatus === 'online' &&
spawnLaunchState === 'confirmed_alive'
) {
launchVisualState = 'settling';
if (isTeamAlive !== false || isTeamProvisioning) {
if (spawnLaunchState === 'failed_to_start' || spawnStatus === 'error') {
launchVisualState = 'error';
} else if (
spawnLaunchState === 'runtime_pending_bootstrap' &&
spawnStatus === 'online' &&
spawnRuntimeAlive === true
) {
launchVisualState = 'runtime_pending';
} else if (
isLaunchStillStarting(
spawnStatus,
spawnLaunchState,
spawnRuntimeAlive,
keepLaunchSettlingVisuals
)
) {
launchVisualState = spawnStatus === 'spawning' ? 'spawning' : 'waiting';
} else if (
isLaunchSettling &&
spawnStatus === 'online' &&
spawnLaunchState === 'confirmed_alive'
) {
launchVisualState = 'settling';
}
}
const spawnBadgeLabel =

View file

@ -38,12 +38,12 @@ import type {
} from './schedule';
import type {
AddMemberRequest,
BoardTaskActivityEntry,
BoardTaskLogStreamResponse,
BoardTaskExactLogDetailResult,
BoardTaskExactLogSummariesResponse,
AddTaskCommentRequest,
AttachmentFileData,
BoardTaskActivityEntry,
BoardTaskExactLogDetailResult,
BoardTaskExactLogSummariesResponse,
BoardTaskLogStreamResponse,
CreateTaskRequest,
CrossTeamMessage,
CrossTeamSendRequest,

View file

@ -556,8 +556,8 @@ describe('ProviderRuntimeSettingsDialog Codex connection flows', () => {
const icon = host.querySelector('[data-testid="provider-api-key-icon"]');
expect(icon).not.toBeNull();
expect(icon?.className).toContain('h-8');
expect(icon?.className).toContain('w-8');
expect(icon?.className).toContain('size-8');
expect(icon?.className).not.toContain('w-8');
expect(icon?.className).toContain('shrink-0');
});