mirror of
https://github.com/stablyai/orca.git
synced 2026-10-29 00:03:37 +00:00
test(renderer): align regressions with durable nested ownership
Update CI-failing expectations for #13341 (process/title no longer reclaim under active launch), add shell/remote/hook edge cases, and use an agent-attributable working title in WorktreeCard status coverage.
This commit is contained in:
@@ -52,8 +52,9 @@ describe('getWorktreeStatus', () => {
|
||||
livePtyIds
|
||||
)
|
||||
).toBe('permission')
|
||||
// Why: status must be agent-attributable (identity or spinner+launch), not a bare keyword.
|
||||
expect(
|
||||
getWorktreeStatus([makeTerminalTab('mimo working')], [{ id: 'browser-1' }], livePtyIds)
|
||||
getWorktreeStatus([makeTerminalTab('✦ Codex')], [{ id: 'browser-1' }], livePtyIds)
|
||||
).toBe('working')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -140,7 +140,8 @@ describe('buildWorktreeAgentRows', () => {
|
||||
expect(rows[0].agentType).toBe('codex')
|
||||
})
|
||||
|
||||
it('prefers an unrelated live title over the launched tab agent for unknown rows', () => {
|
||||
// Why (#13341): unknown hook rows still honor launch ownership over a nested child title.
|
||||
it('keeps launch ownership over an unrelated live title for unknown rows', () => {
|
||||
const rows = buildWorktreeAgentRows({
|
||||
tabs: [makeTab('tab-1', { launchAgent: 'omp', title: '\u280b Codex' })],
|
||||
entries: [
|
||||
@@ -153,7 +154,7 @@ describe('buildWorktreeAgentRows', () => {
|
||||
now: 2000
|
||||
})
|
||||
|
||||
expect(rows[0].agentType).toBe('codex')
|
||||
expect(rows[0].agentType).toBe('omp')
|
||||
})
|
||||
|
||||
it('normalizes live Pi-compatible rows from the launched OMP tab agent', () => {
|
||||
|
||||
@@ -203,22 +203,17 @@ export function resolveTitleDerivedAgentType(
|
||||
const agentType = TITLE_AGENT_LABEL_TO_TYPE[label] ?? 'unknown'
|
||||
const owner = ownerAgentType && ownerAgentType !== 'unknown' ? ownerAgentType : null
|
||||
if (agentType === 'claude') {
|
||||
// Why: Claude's task-title spinner heuristic has no provider identity. In
|
||||
// split panes it can match arbitrary terminal spinners, so sidebar rows only
|
||||
// accept Claude when the title itself names Claude.
|
||||
// Why: spinner heuristic is provider-neutral — require a Claude token.
|
||||
if (!CLAUDE_AGENT_TOKEN_RE.test(title)) {
|
||||
return null
|
||||
}
|
||||
// Why (#8940 + #13341): Claude mentions never steal ownership, and a nested
|
||||
// Claude identity frame under a durable non-Claude owner keeps the parent.
|
||||
// Pane reuse is modeled by clearing launchAgent first (tab-agent path).
|
||||
// Why (#8940/#13341): never steal a non-Claude owner; reclaim after launch clears.
|
||||
if (owner && owner !== 'claude') {
|
||||
return null
|
||||
}
|
||||
return agentType
|
||||
}
|
||||
// Why (#13341): nested Codex/Gemini/... titles must not rebrand a pane whose
|
||||
// launch owner is still a different agent — fall through to ownerAgentType.
|
||||
// Why (#13341): nested child titles keep the durable owner until launch clears.
|
||||
if (owner && agentType !== 'unknown' && agentType !== owner) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -102,4 +102,57 @@ describe('resolveTabAgentFromSignals — nested child identity (#13341)', () =>
|
||||
})
|
||||
).toBe('codex')
|
||||
})
|
||||
|
||||
it('treats shell-foreground as exit so a later process can own the icon', () => {
|
||||
expect(
|
||||
resolveTabAgentFromSignals({
|
||||
hasObservedAgentSignal: true,
|
||||
isRemote: false,
|
||||
title: '✳ Claude Code',
|
||||
hookAgent: null,
|
||||
processAgent: null,
|
||||
processShellForeground: true,
|
||||
launchAgent: 'claude'
|
||||
})
|
||||
).toBeNull()
|
||||
expect(
|
||||
resolveTabAgentFromSignals({
|
||||
hasObservedAgentSignal: true,
|
||||
isRemote: false,
|
||||
title: '✦ Codex',
|
||||
hookAgent: null,
|
||||
processAgent: 'codex',
|
||||
processShellForeground: false,
|
||||
launchAgent: undefined
|
||||
})
|
||||
).toBe('codex')
|
||||
})
|
||||
|
||||
it('keeps remote parent ownership when only a nested child title is visible', () => {
|
||||
// Remote panes lack local process evidence; nested title alone must not rebrand.
|
||||
expect(
|
||||
resolveTabAgentFromSignals({
|
||||
hasObservedAgentSignal: true,
|
||||
isRemote: true,
|
||||
title: '✦ Codex',
|
||||
hookAgent: null,
|
||||
processAgent: null,
|
||||
launchAgent: 'claude'
|
||||
})
|
||||
).toBe('claude')
|
||||
})
|
||||
|
||||
it('lets a live different-group hook outrank launch (explicit takeover)', () => {
|
||||
// Why: hooks are ground truth; fenced nested hooks keep parent agentType upstream.
|
||||
expect(
|
||||
resolveTabAgentFromSignals({
|
||||
hasObservedAgentSignal: true,
|
||||
isRemote: false,
|
||||
title: '✦ Codex',
|
||||
hookAgent: 'codex',
|
||||
processAgent: 'codex',
|
||||
launchAgent: 'claude'
|
||||
})
|
||||
).toBe('codex')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -241,6 +241,7 @@ describe('OpenCode native title tab identity', () => {
|
||||
launchAgent: 'claude'
|
||||
})
|
||||
).toBe('claude')
|
||||
// Why (#13341): nested process under active launch is not stronger than parent ownership.
|
||||
expect(
|
||||
resolveTabAgentFromSignals({
|
||||
hasObservedAgentSignal: false,
|
||||
@@ -251,7 +252,7 @@ describe('OpenCode native title tab identity', () => {
|
||||
sleepingSessionAgent: 'claude',
|
||||
launchAgent: 'claude'
|
||||
})
|
||||
).toBe('codex')
|
||||
).toBe('claude')
|
||||
|
||||
for (const title of [
|
||||
'OpenCode ready',
|
||||
|
||||
@@ -126,7 +126,8 @@ describe('useTabAgent retained completion identity', () => {
|
||||
expect(latestAgent).toBe('gemini')
|
||||
})
|
||||
|
||||
it('lets an explicit cross-agent title reclaim a retained idle pane', async () => {
|
||||
// Why (#13341): active launch ownership is durable; nested Claude title does not reclaim.
|
||||
it('keeps launch ownership over an explicit cross-agent title on a retained idle pane', async () => {
|
||||
const paneKey = makePaneKey(TAB_ID, FOCUSED_LEAF_ID)
|
||||
useAppStore.setState({
|
||||
retainedAgentsByPaneKey: { [paneKey]: retainedEntry(paneKey, 'codex') }
|
||||
@@ -134,7 +135,7 @@ describe('useTabAgent retained completion identity', () => {
|
||||
|
||||
await renderProbe({ ...baseTab, launchAgent: 'codex', title: '✳ Claude Code' })
|
||||
|
||||
expect(latestAgent).toBe('claude')
|
||||
expect(latestAgent).toBe('codex')
|
||||
})
|
||||
|
||||
it('keeps focused launch metadata ahead of sibling retained identity', async () => {
|
||||
|
||||
Reference in New Issue
Block a user