1import {
2 presentThreadShell,
3 type EnvironmentThreadShell,
4} from "@t3tools/client-runtime/state/shell";
5import {
6 EnvironmentId,
7 ProjectId,
8 ProviderInstanceId,
9 ThreadId,
10 type OrchestrationV2ThreadShell,
11} from "@t3tools/contracts";
12import * as DateTime from "effect/DateTime";
13
14const DEFAULT_TIMESTAMP = "2026-01-01T00:00:00.000Z";
15
16export function makeRawThreadShell(
17 input: Partial<OrchestrationV2ThreadShell> = {},
18): OrchestrationV2ThreadShell {
19 const id = input.id ?? ThreadId.make("thread-test");
20 const providerInstanceId = input.providerInstanceId ?? ProviderInstanceId.make("codex");
21 const now = DateTime.makeUnsafe(DEFAULT_TIMESTAMP);
22 return {
23 id,
24 projectId: ProjectId.make("project-test"),
25 title: "Thread",
26 providerInstanceId,
27 modelSelection: { instanceId: providerInstanceId, model: "gpt-5.4" },
28 runtimeMode: "full-access",
29 interactionMode: "default",
30 branch: null,
31 worktreePath: null,
32 activeProviderThreadId: null,
33 lineage: { rootThreadId: id, parentThreadId: null, relationshipToParent: null },
34 forkedFrom: null,
35 createdBy: "user",
36 creationSource: "mobile",
37 latestRunId: null,
38 activeRunId: null,
39 status: "idle",
40 pendingRuntimeRequest: null,
41 latestVisibleMessage: null,
42 latestUserMessageAt: null,
43 hasActionableProposedPlan: false,
44 itemCount: 0,
45 visibleItemCount: 0,
46 createdAt: now,
47 updatedAt: now,
48 archivedAt: null,
49 settledOverride: null,
50 settledAt: null,
51 deletedAt: null,
52 ...input,
53 };
54}
55
56export function makeThreadShellFixture(
57 overrides: Partial<EnvironmentThreadShell> = {},
58): EnvironmentThreadShell {
59 const environmentId = overrides.environmentId ?? EnvironmentId.make("environment-test");
60 const raw = makeRawThreadShell({
61 id: overrides.id,
62 projectId: overrides.projectId,
63 title: overrides.title,
64 providerInstanceId: overrides.providerInstanceId,
65 modelSelection: overrides.modelSelection,
66 runtimeMode: overrides.runtimeMode,
67 interactionMode: overrides.interactionMode,
68 branch: overrides.branch,
69 worktreePath: overrides.worktreePath,
70 });
71 return { ...presentThreadShell(environmentId, raw), ...overrides };
72}