fix(web): reconcile rebased subagent contracts

This commit is contained in:
imccyu
2026-08-01 09:42:18 +08:00
committed by Tianyi Cui
parent d950150cdc
commit 5ef5feb01a
8 changed files with 53 additions and 34 deletions

View File

@@ -93,7 +93,7 @@ const runningCall = (callId: string, name = 'bash'): RunningToolCall => ({
/** Empty sessions-list hook for the global standard-kit seat. */
function emptySessions() {
const store = createSnapshotStore<SessionListState>(
{ ids: [], byId: {}, current: undefined, phase: 'ready', subagentsByParent: {}, currentAddress: undefined, })
{ ids: [], byId: {}, current: undefined, phase: 'ready', subagentsByParent: {}, currentAddress: undefined })
return bindSnapshotSelector(store)
}

View File

@@ -76,7 +76,7 @@ describe('render branch tails', () => {
const chat = createChatStore().create()
chat.actions.select({ turnSeq: 1, callId: 'ghost' } satisfies SelectionTarget)
const emptyList = createSnapshotStore<SessionListState>(
{ ids: [], byId: {}, current: undefined, phase: 'ready', subagentsByParent: {}, currentAddress: undefined, })
{ ids: [], byId: {}, current: undefined, phase: 'ready', subagentsByParent: {}, currentAddress: undefined })
const emptyWorkspaces = createSnapshotStore<WorkspaceListState>({
items: [], archivedSessionIds: [], state: 'idle', phase: 'ready', error: null,
baselinesReady: true, recentWorkspaceId: undefined,
@@ -113,7 +113,7 @@ describe('render branch tails', () => {
const chat = createChatStore().create()
chat.actions.select({ turnSeq: 8, callId: 'p1:code:1', toolName: 'read' } satisfies SelectionTarget)
const emptyList = createSnapshotStore<SessionListState>(
{ ids: [], byId: {}, current: undefined, phase: 'ready', subagentsByParent: {}, currentAddress: undefined, })
{ ids: [], byId: {}, current: undefined, phase: 'ready', subagentsByParent: {}, currentAddress: undefined })
const emptyWorkspaces = createSnapshotStore<WorkspaceListState>({
items: [], archivedSessionIds: [], state: 'idle', phase: 'ready', error: null,
baselinesReady: true, recentWorkspaceId: undefined,

View File

@@ -46,6 +46,8 @@
border: 1px solid var(--dsw-alias-border-l2);
border-radius: 12px;
background: var(--dsw-specific-menu);
--dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);
--dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);
box-shadow: var(--dsw-shadow-lv3);
}

View File

@@ -273,6 +273,19 @@ function sessionBlank(session: Session): boolean {
return !session.events.some(event => event.type === 'turn/start')
}
/** Shared Session-header projection for list baselines and creation frames. */
function sessionListFields(header: SessionHeader): {
parentSessionId?: SessionId
origin?: 'subagent'
cwd?: string
} {
return {
...header.parentSession === undefined ? {} : { parentSessionId: header.parentSession },
...header.origin === undefined ? {} : { origin: header.origin },
...header.cwd === undefined ? {} : { cwd: header.cwd },
}
}
/** SessionSummary projection for attached (in-memory) sessions. */
function summarize(session: Session, running: boolean): SessionSummary {
return {
@@ -282,9 +295,7 @@ function summarize(session: Session, running: boolean): SessionSummary {
updatedAt: lastActivityTime(session.events) ?? session.header.createdAt,
running,
blank: sessionBlank(session),
...session.header.parentSession === undefined ? {} : { parentSessionId: session.header.parentSession },
...session.header.origin === undefined ? {} : { origin: session.header.origin },
...session.header.cwd === undefined ? {} : { cwd: session.header.cwd },
...sessionListFields(session.header),
}
}
@@ -2378,10 +2389,8 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
// Derived at frame time like summarize(); a just-created session
// has run no turn yet, so this is constantly true in practice.
blank: sessionBlank(session),
...session.header.parentSession === undefined ? {} : { parentSessionId: session.header.parentSession },
...session.header.origin === undefined ? {} : { origin: session.header.origin },
// cwd rides the frame so the client list needs no refresh to group the new session.
...session.header.cwd === undefined ? {} : { cwd: session.header.cwd },
// Including cwd lets the client group the new session without refreshing the list.
...sessionListFields(session.header),
}))
}),
ctx.on('session/disposed', (session: Session) => {