diff --git a/src/renderer/components/chat/SessionContextPanel/components/SessionContextHeader.tsx b/src/renderer/components/chat/SessionContextPanel/components/SessionContextHeader.tsx index 0879452a..748b55cc 100644 --- a/src/renderer/components/chat/SessionContextPanel/components/SessionContextHeader.tsx +++ b/src/renderer/components/chat/SessionContextPanel/components/SessionContextHeader.tsx @@ -16,6 +16,7 @@ import { formatCostUsd } from '@shared/utils/costFormatting'; import { ArrowDownWideNarrow, FileText, LayoutList, X } from 'lucide-react'; import { formatTokens } from '../utils/formatting'; +import { formatPercentOfTotal } from '@renderer/utils/contextMath'; import { SessionContextHelpTooltip } from './SessionContextHelpTooltip'; @@ -110,7 +111,7 @@ export const SessionContextHeader = ({ )} {/* Percentage of total */} - {totalSessionTokens !== undefined && totalSessionTokens > 0 && ( + {formatPercentOfTotal(totalTokens, totalSessionTokens) && ( - {Math.min((totalTokens / totalSessionTokens) * 100, 100).toFixed(1)}% of total + {formatPercentOfTotal(totalTokens, totalSessionTokens)} )} diff --git a/src/renderer/components/chat/SessionContextPanel/index.tsx b/src/renderer/components/chat/SessionContextPanel/index.tsx index 83b7ac8f..6866f0ad 100644 --- a/src/renderer/components/chat/SessionContextPanel/index.tsx +++ b/src/renderer/components/chat/SessionContextPanel/index.tsx @@ -29,6 +29,7 @@ import { SECTION_TOOL_OUTPUTS, SECTION_USER_MESSAGES, } from './types'; +import { sumContextInjectionTokens } from '@renderer/utils/contextMath'; import type { ContextViewMode, SectionType, SessionContextPanelProps } from './types'; import type { @@ -133,7 +134,7 @@ export const SessionContextPanel = ({ // Calculate total tokens const totalTokens = useMemo( - () => injections.reduce((sum, inj) => sum + inj.estimatedTokens, 0), + () => sumContextInjectionTokens(injections), [injections] ); diff --git a/src/renderer/components/team/ProvisioningProgressBlock.tsx b/src/renderer/components/team/ProvisioningProgressBlock.tsx index 4fdd94c7..64fd0789 100644 --- a/src/renderer/components/team/ProvisioningProgressBlock.tsx +++ b/src/renderer/components/team/ProvisioningProgressBlock.tsx @@ -195,10 +195,8 @@ export const ProvisioningProgressBlock = ({ {STEP_ORDER.filter((s): s is ProvisioningStep => s !== 'ready').map((step, index) => { const isDone = currentStepIndex >= 0 && index < currentStepIndex; const isCurrent = currentStepIndex >= 0 && index === currentStepIndex; - return (
- {/* eslint-disable tailwindcss/no-custom-classname -- theme CSS vars */} {STEP_LABELS[step]} - {/* eslint-enable tailwindcss/no-custom-classname -- end theme CSS vars block */} {index < STEP_ORDER.filter((s) => s !== 'ready').length - 1 ? ( ) : null} diff --git a/src/renderer/components/team/TeamDetailView.tsx b/src/renderer/components/team/TeamDetailView.tsx index 4b7cb936..e051da90 100644 --- a/src/renderer/components/team/TeamDetailView.tsx +++ b/src/renderer/components/team/TeamDetailView.tsx @@ -20,6 +20,7 @@ import { cn } from '@renderer/lib/utils'; import { useStore } from '@renderer/store'; import { useTabUI } from '@renderer/hooks/useTabUI'; import { createChipFromSelection } from '@renderer/utils/chipUtils'; +import { formatPercentOfTotal, sumContextInjectionTokens } from '@renderer/utils/contextMath'; import { formatProjectPath } from '@renderer/utils/pathDisplay'; import { buildTaskCountsByOwner, normalizePath } from '@renderer/utils/pathNormalize'; import { nameColorSet } from '@renderer/utils/projectColor'; @@ -434,14 +435,14 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele return { allContextInjections: injections, lastAiGroupTotalTokens: totalTokens }; }, [leadSessionLoaded, leadSessionContextStats, leadConversation, selectedContextPhase, leadSessionPhaseInfo]); - const visibleContextTokens = useMemo(() => { - return allContextInjections.reduce((sum, inj) => sum + (inj.estimatedTokens ?? 0), 0); - }, [allContextInjections]); - - const visibleContextPercentOfTotal = useMemo(() => { - if (lastAiGroupTotalTokens === undefined || lastAiGroupTotalTokens <= 0) return null; - return Math.min((visibleContextTokens / lastAiGroupTotalTokens) * 100, 100); - }, [visibleContextTokens, lastAiGroupTotalTokens]); + const visibleContextTokens = useMemo( + () => sumContextInjectionTokens(allContextInjections), + [allContextInjections] + ); + const visibleContextPercentLabel = useMemo( + () => formatPercentOfTotal(visibleContextTokens, lastAiGroupTotalTokens), + [visibleContextTokens, lastAiGroupTotalTokens] + ); useEffect(() => { if (!projectId) return; @@ -863,9 +864,12 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele className="relative size-full flex-1 overflow-auto p-4" data-team-name={teamName} > - {/* Sticky context button in top-right while scrolling */} + {/* Context button pinned to bottom-right of viewport */} {leadSessionId && ( -
+