/**
 * Owns frontend-neutral projection of persisted turn presentation metadata.
 *
 * Core owns which tool facts become durable turn presentation metadata. This
 * service owns the shared client-side shape that web-v2 and cli-v2 can render
 * differently. It does not parse raw traces, inspect tool payloads, or decide
 * host-specific layout, keyboard shortcuts, or collapse state.
 */
export class ClientSharedSessionTurnPresentationService {
    static projectConversationTimeline(session) {
        if (!session) {
            return [];
        }
        const placedTurnIds = new Set();
        const timeline = session.messages.flatMap((message) => {
            const messageItem = {
                type: 'message',
                id: message.id,
                message,
            };
            if (message.role !== 'user') {
                return [messageItem];
            }
            const turn = ClientSharedSessionTurnPresentationService.findUnplacedTurnForPrompt({
                turns: session.turns,
                placedTurnIds,
                prompt: message.text,
            });
            if (!turn) {
                return [messageItem];
            }
            placedTurnIds.add(turn.id);
            return [
                messageItem,
                ...ClientSharedSessionTurnPresentationService.projectConversationActivityGroup(turn),
            ];
        });
        return [
            ...timeline,
            ...session.turns
                .filter((turn) => !placedTurnIds.has(turn.id))
                .flatMap((turn) => ClientSharedSessionTurnPresentationService.projectConversationActivityGroup(turn)),
        ];
    }
    static projectTurnActivities(session) {
        return session?.turns.flatMap((turn) => (ClientSharedSessionTurnPresentationService.projectTurnActivityItems(turn))) ?? [];
    }
    static projectTurnActivityItems(turn) {
        return turn.presentation?.timelineItems.map((activity) => ({
            id: activity.id,
            turnId: turn.id,
            turnPrompt: turn.prompt,
            activity,
        })) ?? [];
    }
    static projectConversationActivityGroup(turn) {
        const activities = turn.presentation?.timelineItems ?? [];
        if (activities.length === 0) {
            return [];
        }
        return [{
                type: 'turn_activity_group',
                id: `${turn.id}:activity-group`,
                turnId: turn.id,
                turnPrompt: turn.prompt,
                activities,
            }];
    }
    static findUnplacedTurnForPrompt({ placedTurnIds, prompt, turns, }) {
        return turns.find((turn) => !placedTurnIds.has(turn.id) && turn.prompt.trim() === prompt.trim());
    }
}
//# sourceMappingURL=session-turn-presentation-service.js.map