import { scopeProjectRef } from "@t3tools/client-runtime/environment"; import type { EnvironmentId, ProjectId, ScopedProjectRef } from "@t3tools/contracts"; import type { DraftThreadEnvMode } from "../composerDraftStore"; interface ThreadContextLike { environmentId: EnvironmentId; projectId: ProjectId; } interface NewThreadHandler { ( projectRef: ScopedProjectRef, options?: { branch?: string | null; worktreePath?: string | null; envMode?: DraftThreadEnvMode; startFromOrigin?: boolean; }, // The opened draft's identity, which most callers have no use for. ): Promise; } export interface ChatThreadActionContext { readonly activeDraftThread: ThreadContextLike | null; readonly activeThread: ThreadContextLike | undefined; readonly defaultProjectRef: ScopedProjectRef | null; readonly handleNewThread: NewThreadHandler; } export function resolveNewDraftStartFromOrigin(input: { envMode: DraftThreadEnvMode; newWorktreesStartFromOrigin: boolean; }): boolean { return input.envMode === "worktree" && input.newWorktreesStartFromOrigin; } export function resolveThreadActionProjectRef( context: ChatThreadActionContext, ): ScopedProjectRef | null { if (context.activeThread) { return scopeProjectRef(context.activeThread.environmentId, context.activeThread.projectId); } if (context.activeDraftThread) { return scopeProjectRef( context.activeDraftThread.environmentId, context.activeDraftThread.projectId, ); } return context.defaultProjectRef; } // New threads inherit only the *project* from the current context. Branch, // worktree, and env mode always come from the user's configured defaults — // carrying them over from the viewed thread meant "new thread" silently // reused checkouts and branches. Explicit affordances (branch toolbar's // "new thread in this worktree") pass those options to handleNewThread // directly instead. export async function startNewThreadFromContext( context: ChatThreadActionContext, ): Promise { const projectRef = resolveThreadActionProjectRef(context); if (!projectRef) { return false; } await context.handleNewThread(projectRef); return true; }