diff --git a/src/renderer/components/ui/SessionSpinner.tsx b/src/renderer/components/ui/SessionSpinner.tsx
new file mode 100644
index 0000000..654f14f
--- /dev/null
+++ b/src/renderer/components/ui/SessionSpinner.tsx
@@ -0,0 +1,54 @@
+/**
+ * Five-bar radial spinner for session "agent run in flight" indicators. Uses
+ * staggered `animate-spin` layers; honors reduced-motion via the global
+ * stylesheet when `data-reduced-motion="true"` is set on .
+ */
+import type { ComponentProps } from 'react';
+import { cn } from '@/renderer/lib/cn';
+
+interface SessionSpinnerProps extends ComponentProps<'div'> {
+ size?: number;
+ invert?: boolean;
+ disabled?: boolean;
+}
+
+export function SessionSpinner({
+ size = 16,
+ invert,
+ disabled,
+ className,
+ ...props
+}: SessionSpinnerProps) {
+ if (disabled) return null;
+
+ const sizePx = `${size}px`;
+ const barWidth = `${(size * 0.2).toFixed(2)}px`;
+ const barHeight = `${(size * 0.075).toFixed(2)}px`;
+
+ return (
+
+ {[...Array(5)].map((_, i) => (
+
+ ))}
+
+ );
+}
diff --git a/src/renderer/components/ui/index.ts b/src/renderer/components/ui/index.ts
index 26a0c55..bc1d79f 100644
--- a/src/renderer/components/ui/index.ts
+++ b/src/renderer/components/ui/index.ts
@@ -5,6 +5,7 @@ export { EmptyState } from './EmptyState';
export { Badge } from './Badge';
export { Kbd } from './Kbd';
export { Spinner } from './Spinner';
+export { SessionSpinner } from './SessionSpinner';
export { SuccessCheck } from './SuccessCheck';
export { CircularProgress } from './CircularProgress';
export { Waveform } from './Waveform';
diff --git a/src/renderer/features/sessions/SessionRow.tsx b/src/renderer/features/sessions/SessionRow.tsx
index c50896e..42634a6 100644
--- a/src/renderer/features/sessions/SessionRow.tsx
+++ b/src/renderer/features/sessions/SessionRow.tsx
@@ -14,7 +14,7 @@
import { useEffect, useRef, useState } from 'react';
import { CircleDot, GitBranch, Pin, Archive, MoreHorizontal } from 'lucide-react';
import type { Session, SessionStatus } from '@shared/types';
-import { Badge, DiffStat, IconButton, Spinner } from '@/renderer/components/ui';
+import { Badge, DiffStat, IconButton, SessionSpinner } from '@/renderer/components/ui';
import { cn } from '@/renderer/lib/cn';
import { relativeTime } from '@/renderer/lib/format';
import { useSessionStore } from '@/renderer/stores/useSessionStore';
@@ -96,7 +96,7 @@ export function SessionRow({
) : running ? (
-
+
) : (
)}
diff --git a/src/renderer/features/sessions/WorktreeTabs.tsx b/src/renderer/features/sessions/WorktreeTabs.tsx
index 10825b4..4a09421 100644
--- a/src/renderer/features/sessions/WorktreeTabs.tsx
+++ b/src/renderer/features/sessions/WorktreeTabs.tsx
@@ -12,7 +12,7 @@
*/
import { AlertTriangle, GitBranch, X } from 'lucide-react';
import type { Session } from '@shared/types';
-import { Badge, Spinner } from '@/renderer/components/ui';
+import { Badge, SessionSpinner } from '@/renderer/components/ui';
import { cn } from '@/renderer/lib/cn';
import { useSessionStore } from '@/renderer/stores/useSessionStore';
import { useIsSessionRunning } from './useSessionRunning';
@@ -93,7 +93,7 @@ function WorktreeTab({
)}
>
{running ? (
-
+
) : missing ? (
) : (
diff --git a/src/renderer/features/workspace/CenterWorkspace.tsx b/src/renderer/features/workspace/CenterWorkspace.tsx
index e98316f..1d55681 100644
--- a/src/renderer/features/workspace/CenterWorkspace.tsx
+++ b/src/renderer/features/workspace/CenterWorkspace.tsx
@@ -13,7 +13,7 @@
*/
import { useEffect, useState } from 'react';
import { AlertTriangle, CircleDot, GitBranch, Plus, TerminalSquare } from 'lucide-react';
-import { DiffStat, IconButton, Spinner } from '@/renderer/components/ui';
+import { DiffStat, IconButton, SessionSpinner, Spinner } from '@/renderer/components/ui';
import { useIsSessionRunning } from '@/renderer/features/sessions/useSessionRunning';
import { WorktreeTabs } from '@/renderer/features/sessions/WorktreeTabs';
import { ServicesStrip } from '@/renderer/features/sessions/ServicesStrip';
@@ -200,7 +200,7 @@ function SessionHeader({
const revalidating = useResumeStore((s) => s.bySession[sessionId]?.phase === 'checking');
return (
- {running ? : }
+ {running ? : }
{title}
{branch}