mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 08:03:39 +00:00
fix(terminal): fold only bare identity frames into the group token
A legacy "π - <session> - <cwd>" title is Pi-compatible too, so folding every profile match collapsed two different sessions to the same signature and suppressed the change outright — reintroducing #16093 through the churn signature. Fold only exact bare identity frames, matched per wrapper segment, so semantic session titles keep comparing on their own text. Co-authored-by: Seongho.Bak <49228032+psh4607@users.noreply.github.com>
This commit is contained in:
@@ -224,6 +224,27 @@ describe('OMP-owned tab title across interleaved OMP/Pi spinner frames', () => {
|
||||
expect(store.getState().runtimePaneTitlesByTabId[TAB_ID]?.[PANE_ID]).toBe('⠙ Codex')
|
||||
})
|
||||
|
||||
// Why: a legacy "π - <session> - <cwd>" frame is Pi-compatible too, but its text is real session
|
||||
// state. Folding it into the group token would make two different sessions compare equal and
|
||||
// suppress the change outright — the #16093 complaint, reintroduced through the signature.
|
||||
it('still commits a change between two semantic session titles', () => {
|
||||
const store = createTestStore()
|
||||
seedOmpTab(store)
|
||||
|
||||
store.getState().setRuntimePaneTitle(TAB_ID, PANE_ID, 'π - fixing the sidebar - orca')
|
||||
let commits = 0
|
||||
const unsubscribe = store.subscribe(() => {
|
||||
commits += 1
|
||||
})
|
||||
store.getState().setRuntimePaneTitle(TAB_ID, PANE_ID, 'π - writing the tests - orca')
|
||||
unsubscribe()
|
||||
|
||||
expect(commits).toBe(1)
|
||||
expect(store.getState().runtimePaneTitlesByTabId[TAB_ID]?.[PANE_ID]).toBe(
|
||||
'π - writing the tests - orca'
|
||||
)
|
||||
})
|
||||
|
||||
// Why: owner-pinning must stay scoped to bare identity frames. A semantic session title carries
|
||||
// text no agent profile can reproduce, so relabeling it to "OMP ready" would lose real
|
||||
// information — the complaint in #16093, which this fix must not reintroduce.
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
SYNTHETIC_AGENT_TITLE_PROFILES,
|
||||
type SyntheticAgentTitleProfile
|
||||
} from './synthetic-agent-title'
|
||||
import { isLegacyPiCompatibleTitle } from './pi-compatible-synthetic-title'
|
||||
import {
|
||||
getPiCompatibleSyntheticAgentLabel,
|
||||
isLegacyPiCompatibleTitle
|
||||
} from './pi-compatible-synthetic-title'
|
||||
import { getWrapperTitleSegments } from './terminal-title-wrapper-segments'
|
||||
|
||||
type TitleProfileMatch = {
|
||||
@@ -67,20 +70,30 @@ export function hasCompatibleAgentTitleIdentity(title: string): boolean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the agent-identity segment of a title with its identity-group name, leaving any
|
||||
* wrapper prefix intact ("zsh | ⠋ Pi" and "zsh | ⠋ OMP" both become "zsh | pi-compatible").
|
||||
* Replaces a bare agent-identity frame with its identity-group name, leaving any wrapper prefix
|
||||
* intact ("zsh | ⠋ Pi" and "zsh | ⠙ OMP" both become "zsh | pi-compatible").
|
||||
*
|
||||
* Why: members of a group are the same agent to a pane — OMP wraps Pi and both harnesses emit
|
||||
* frames — so which one a frame names is decoration, not state. Callers comparing consecutive
|
||||
* frames need them to compare equal; callers rendering the title must not use this.
|
||||
* frames need those to compare equal; callers rendering the title must not use this.
|
||||
*
|
||||
* Why only bare frames: a legacy "π - <session> - <cwd>" title is also Pi-compatible, but its
|
||||
* text is real session state. Folding it would make two different sessions compare equal and
|
||||
* suppress the change outright (#16093).
|
||||
*/
|
||||
export function collapseCompatibleAgentTitleIdentity(title: string): string {
|
||||
const source = getProfileForTitle(title)
|
||||
const group = source?.profile.titleIdentityGroup
|
||||
if (!group) {
|
||||
return title
|
||||
for (const segment of getWrapperTitleSegments(title)) {
|
||||
const label = getPiCompatibleSyntheticAgentLabel(segment)
|
||||
const group = label
|
||||
? SYNTHETIC_AGENT_TITLE_PROFILES[label.toLowerCase()]?.titleIdentityGroup
|
||||
: undefined
|
||||
if (!group) {
|
||||
continue
|
||||
}
|
||||
const at = title.lastIndexOf(segment)
|
||||
return at === -1 ? group : title.slice(0, at) + group
|
||||
}
|
||||
return title.replace(source.sourceTitle, group)
|
||||
return title
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user