import { create } from "zustand"; import type { ComposerAttachment } from "@/attachments/types"; import type { AgentProvider } from "@getpaseo/protocol/agent-types"; import type { WorkspaceDraftTabSetup } from "@/workspace-tabs/model"; export interface PendingWorkspaceDraftSubmission { serverId: string; workspaceId: string; draftId: string; text: string; attachments: ComposerAttachment[]; cwd: string; provider: AgentProvider; clientMessageId: string; timestamp: number; modeId?: string; model?: string; thinkingOptionId?: string; featureValues?: Record; allowEmptyText?: boolean; } export interface PendingWorkspaceDraftSetup { setup: WorkspaceDraftTabSetup; sourceDirectory?: string | null; } interface WorkspaceDraftSubmissionState { pendingByDraftId: Record; setupByDraftId: Record; setPending: (submission: PendingWorkspaceDraftSubmission) => void; setDraftSetup: (input: { draftId: string; setup: WorkspaceDraftTabSetup; sourceDirectory?: string | null; }) => void; clearDraftSetup: (input: { draftId: string }) => void; consumePending: (input: { serverId: string; workspaceId: string; draftId: string; }) => PendingWorkspaceDraftSubmission | null; } function matchesPendingSubmission( pending: PendingWorkspaceDraftSubmission | null | undefined, input: { serverId: string; workspaceId: string; draftId: string }, ): pending is PendingWorkspaceDraftSubmission { return ( pending?.serverId === input.serverId && pending.workspaceId === input.workspaceId && pending.draftId === input.draftId ); } function normalizeDraftId(draftId: string): string { return draftId.trim(); } export const useWorkspaceDraftSubmissionStore = create( (set, get) => ({ pendingByDraftId: {}, setupByDraftId: {}, setPending: (submission) => set((state) => ({ pendingByDraftId: { ...state.pendingByDraftId, [submission.draftId]: submission, }, })), setDraftSetup: ({ draftId, setup, sourceDirectory }) => { const normalizedDraftId = normalizeDraftId(draftId); if (!normalizedDraftId) return; set((state) => ({ setupByDraftId: { ...state.setupByDraftId, [normalizedDraftId]: { setup, sourceDirectory: sourceDirectory ?? null }, }, })); }, clearDraftSetup: ({ draftId }) => { const normalizedDraftId = normalizeDraftId(draftId); if (!normalizedDraftId) return; set((state) => { if (!state.setupByDraftId[normalizedDraftId]) return state; const { [normalizedDraftId]: _removed, ...setupByDraftId } = state.setupByDraftId; return { setupByDraftId }; }); }, consumePending: (input) => { const pending = get().pendingByDraftId[input.draftId]; if (!matchesPendingSubmission(pending, input)) { return null; } set((state) => { if (!matchesPendingSubmission(state.pendingByDraftId[input.draftId], input)) { return state; } const { [input.draftId]: _removed, ...rest } = state.pendingByDraftId; return { pendingByDraftId: rest }; }); return pending; }, }), );