1import type { EnvironmentId, ThreadId, WorktreeSetupSnapshot } from "@t3tools/contracts";
2import { resolveVisibleWorktreeSetup } from "@t3tools/client-runtime/worktree-setup";
3import { useState } from "react";
4import { useEnvironmentQuery } from "../../state/query";
5import { vcsEnvironment } from "../../state/vcs";
6import { resolveWorktreeSetupSnapshot } from "./worktree-setup-state";
7
8export function useWorktreeSetup(input: {
9 environmentId: EnvironmentId | null;
10 threadId: ThreadId | null;
11 preparing: boolean;
12 turnStarted: boolean;
13 followUpSent: boolean;
14}) {
15 const key = JSON.stringify([input.environmentId, input.threadId]);
16 const [held, setHeld] = useState<{ key: string; snapshot: WorktreeSetupSnapshot } | null>(null);
17 const live = held?.key === key ? held.snapshot : null;
18 const query = useEnvironmentQuery(
19 input.environmentId &&
20 input.threadId &&
21 (live?.phase === "running" || (!live && input.preparing))
22 ? vcsEnvironment.worktreeSetup({
23 environmentId: input.environmentId,
24 input: { threadId: input.threadId },
25 })
26 : null,
27 );
28 const snapshot = resolveWorktreeSetupSnapshot(input.threadId, query.data, live);
29 // Hold the newest snapshot so it survives the subscription closing once setup stops running.
30 // Set during render so each emission commits once; the resolver returns `live` by identity
31 // on the next pass, which ends the update.
32 if (snapshot && snapshot !== live) setHeld({ key, snapshot });
33 return {
34 snapshot,
35 visible: resolveVisibleWorktreeSetup({
36 live: snapshot,
37 recorded: null,
38 turnStarted: input.turnStarted,
39 followUpSent: input.followUpSent,
40 }),
41 };
42}