| 1 | import type { EnvironmentProject } from "@t3tools/client-runtime/state/shell"; |
| 2 | import type { VcsRef } from "@t3tools/client-runtime/state/vcs"; |
| 3 | import { |
| 4 | type AtomCommandResult, |
| 5 | mapAtomCommandResult, |
| 6 | } from "@t3tools/client-runtime/state/runtime"; |
| 7 | import type { VcsSwitchRefInput, VcsSwitchRefResult } from "@t3tools/contracts"; |
| 8 | import * as Cause from "effect/Cause"; |
| 9 | import { AsyncResult } from "effect/reactivity"; |
| 10 | |
| 11 | import { shouldCheckoutNewTaskBranch } from "./new-task-context-presentation"; |
| 12 | |
| 13 | /** Resolve a composer branch only after its checkout succeeds. Existing worktrees |
| 14 | * and new-worktree base selections already identify a separate workspace. */ |
| 15 | export async function checkoutNewTaskBranch<E>(input: { |
| 16 | readonly branch: VcsRef; |
| 17 | readonly project: Pick<EnvironmentProject, "environmentId" | "workspaceRoot"> | null; |
| 18 | readonly workspaceMode: "local" | "worktree"; |
| 19 | readonly switchRef: (request: { |
| 20 | readonly environmentId: EnvironmentProject["environmentId"]; |
| 21 | readonly input: VcsSwitchRefInput; |
| 22 | }) => Promise<AtomCommandResult<VcsSwitchRefResult, E>>; |
| 23 | }): Promise<AtomCommandResult<VcsRef, E | Error>> { |
| 24 | if (!input.project) { |
| 25 | return AsyncResult.failure( |
| 26 | Cause.fail(new Error("The selected project is unavailable. Reconnect and try again.")), |
| 27 | ); |
| 28 | } |
| 29 | if ( |
| 30 | !shouldCheckoutNewTaskBranch({ |
| 31 | branchIsCurrent: input.branch.current, |
| 32 | branchWorktreePath: input.branch.worktreePath, |
| 33 | workspaceMode: input.workspaceMode, |
| 34 | }) |
| 35 | ) { |
| 36 | return AsyncResult.success(input.branch); |
| 37 | } |
| 38 | |
| 39 | const result = await input.switchRef({ |
| 40 | environmentId: input.project.environmentId, |
| 41 | input: { cwd: input.project.workspaceRoot, refName: input.branch.name }, |
| 42 | }); |
| 43 | return mapAtomCommandResult(result, (value) => ({ |
| 44 | ...input.branch, |
| 45 | current: true, |
| 46 | isRemote: false, |
| 47 | name: value.refName ?? input.branch.name, |
| 48 | })); |
| 49 | } |