diff --git a/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.fixture.tsx b/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.fixture.tsx
index 5edbf4a35e8..c1cb0d8be72 100644
--- a/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.fixture.tsx
+++ b/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.fixture.tsx
@@ -11,6 +11,8 @@ import {
type CloudStripActions
} from './CloudAgentSignInStrip'
import { cloudAgentStripModel } from './cloud-agent-strip-model'
+import { cloudRunningStripModel } from './cloud-running-strip-model'
+import type { CloudRunningStrip } from '@/lib/orca-cloud/cloud-running-agent-signout'
const noop = (): void => {}
const ACTIONS: CloudStripActions = {
@@ -24,29 +26,34 @@ const ACTIONS: CloudStripActions = {
const PROMPT = 'Fix the flaky auth test and open a PR'
function Pane({
- reason,
+ reason = 'accountExpired',
view = null,
agent = 'claude',
- width = 900
+ width = 900,
+ running
}: {
- reason: CloudAgentStripReason
+ reason?: CloudAgentStripReason
view?: AgentSignInGateView | null
agent?: HostAgentSignInAgent
width?: number
+ /** RA-11: the strip over a running agent instead of a held launch. */
+ running?: CloudRunningStrip
}): React.JSX.Element {
- const model = cloudAgentStripModel({
- agent,
- reason,
- view,
- hostLabel: translate('agentSignInStrip.sandbox', 'the sandbox'),
- t: translate
- })
+ const model = running
+ ? cloudRunningStripModel(running, translate)
+ : cloudAgentStripModel({
+ agent,
+ reason,
+ view,
+ hostLabel: translate('agentSignInStrip.sandbox', 'the sandbox'),
+ t: translate
+ })
return (
{/* Stands in for a terminal pane: its title row (split, close) stays above the strip. */}
@@ -64,14 +71,21 @@ function Pane({
-
- ~/acme/web $
-
+ {/* The terminal: it starts below the strip (reserved, never covered) and keeps its rows. */}
+
+ {running ? (
+ <>
+
⏺ Reading src/auth/session.ts…
+
⏺ API Error: 401 · Not logged in · Run /login
+ >
+ ) : null}
+
~/acme/web $
+
)
@@ -128,3 +142,22 @@ export const waitingNarrow = fixture({
export const needExpiredNarrow = fixture({ reason: 'accountExpired', width: 520 })
/** Below 360 px: one line and Renew; the detail stays the region's description. */
export const needExpiredCompact = fixture({ reason: 'accountExpired', width: 320 })
+
+/** RA-11 state 1: Claude was running when its Orca-account sign-in expired. */
+export const runningExpired = fixture({ running: { phase: 'expired', agent: 'claude' } })
+export const runningExpiredCompact = fixture({
+ running: { phase: 'expired', agent: 'claude' },
+ width: 320
+})
+/** RA-11 state 2: renewed; this pane's agent still needs a restart (resumes its conversation). */
+export const runningRenewed = fixture({
+ running: { phase: 'renewed', agent: 'claude', resumable: true }
+})
+/** RA-11 state 2 when the session can't be resumed. */
+export const runningRenewedFresh = fixture({
+ running: { phase: 'renewed', agent: 'claude', resumable: false }
+})
+export const runningRenewedNarrow = fixture({
+ running: { phase: 'renewed', agent: 'claude', resumable: true },
+ width: 520
+})
diff --git a/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.tsx b/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.tsx
index 42db438513f..ff6ab3ba3e4 100644
--- a/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.tsx
+++ b/src/renderer/src/components/agent-sign-in-strip/CloudAgentSignInStrip.tsx
@@ -23,6 +23,7 @@ import {
} from '@/components/ui/dropdown-menu'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'
+import { useReservePaneTopSpace } from '../terminal-pane/appearance/pane-top-banner/PaneTopWarningBanner'
import type {
CloudStripModel,
CloudStripPrimary,
@@ -69,11 +70,15 @@ function useLiveStripWidth(
* buttons stay visible and clickable while it shows (RA-1). The pane and its fixture share it.
*/
export function CloudStripLayer({ children }: { children: React.ReactNode }): React.JSX.Element {
+ // A pane-top banner (RA-11): the pane reserves its height and the terminal refits below it, so
+ // no row sits under the strip. The spacer keeps it below a chromeless pane's title-row buttons.
+ const ref = useReservePaneTopSpace()
return (
-
+
)
@@ -282,12 +287,12 @@ export function CloudAgentSignInStrip({
) : null}
{/* Renew is the whole action and the strip leaves on its own; Escape still cancels. */}
- {model.status === 'done' || primary?.action.kind === 'renew' ? null : (
+ {!model.dismiss && (model.status === 'done' || primary?.action.kind === 'renew') ? null : (