import { type AgentSessionImportSource, ChatAttachment, CheckpointRef, EventId, MessageId, ProjectId, ThreadId, type ThreadPullRequestLink, ThreadLinkedPullRequest, TurnId, ProviderInstanceId,} from "@t3tools/contracts";import { assert, it } from "@effect/vitest";import * as NodeServices from "@effect/platform-node/NodeServices";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Schema from "effect/Schema";import * as SqlClient from "effect/unstable/sql/SqlClient"; import { SqlitePersistenceMemory } from "../../persistence/Layers/Sqlite.ts";import * as RepositoryIdentityResolver from "../../project/RepositoryIdentityResolver.ts";import { ORCHESTRATION_PROJECTOR_NAMES } from "./ProjectionPipeline.ts";import { OrchestrationProjectionSnapshotQueryLive } from "./ProjectionSnapshotQuery.ts";import * as ThreadBackgroundLiveness from "../ThreadBackgroundLiveness.ts";import * as ThreadPlanProgress from "../ThreadPlanProgress.ts";import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts";import { encodeThreadDetailPageCursor } from "../threadDetailCursor.ts";import { projectThreadDetailSnapshot } from "../ActivityPayloadProjection.ts";import { makeSqlStatementCounter } from "../../../integration/SqlStatementCounter.integration.ts"; const asProjectId = (value: string): ProjectId => ProjectId.make(value);const asTurnId = (value: string): TurnId => TurnId.make(value);const asMessageId = (value: string): MessageId => MessageId.make(value);const asEventId = (value: string): EventId => EventId.make(value);const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.make(value);const encodeChatAttachments = Schema.encodeEffect( Schema.fromJsonString(Schema.Array(ChatAttachment)),);const encodeThreadLinkedPullRequest = Schema.encodeSync( Schema.fromJsonString(ThreadLinkedPullRequest),); const projectionSnapshotLayer = it.layer( OrchestrationProjectionSnapshotQueryLive.pipe( Layer.provide(ThreadBackgroundLiveness.layer), Layer.provide(ThreadPlanProgress.layer), Layer.provideMerge(RepositoryIdentityResolver.layer), Layer.provideMerge(SqlitePersistenceMemory), Layer.provideMerge(NodeServices.layer), ),); projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { it.effect("hydrates read model from projection tables and computes snapshot sequence", () => Effect.gen(function* () { const snapshotQuery = yield* ProjectionSnapshotQuery; const sql = yield* SqlClient.SqlClient; const branchPullRequest = { projectId: asProjectId("project-1"), repository: "pingdotgg/t3code", number: 43, url: "https://github.com/pingdotgg/t3code/pull/43", }; yield* sql`DELETE FROM projection_projects`; yield* sql`DELETE FROM projection_state`; yield* sql`DELETE FROM projection_thread_proposed_plans`; yield* sql`DELETE FROM projection_thread_pull_requests`; yield* sql`DELETE FROM projection_turns`; yield* sql` INSERT INTO projection_projects ( project_id, title, workspace_root, default_model_selection_json, scripts_json, created_at, updated_at, deleted_at ) VALUES ( 'project-1', 'Project 1', '/tmp/project-1', '{"provider":"codex","model":"gpt-5-codex"}', '[{"id":"script-1","name":"Build","command":"bun run build","icon":"build","runOnWorktreeCreate":false}]', '2026-02-24T00:00:00.000Z', '2026-02-24T00:00:01.000Z', NULL ) `; // A merged link plus a newer open one: the multi-link projection must // resolve to the open pull request, not the stale JSON column below. yield* sql` INSERT INTO projection_thread_pull_requests ( thread_id, host, repository, number, url, source, linked_at, snapshot_json, stack_json ) VALUES ( 'thread-1', 'github.com', 'pingdotgg/t3code', 41, 'https://github.com/pingdotgg/t3code/pull/41', 'created', '2026-02-24T00:00:02.500Z', '{"state":"merged","title":"Groundwork","headBranch":"feat/groundwork","baseBranch":"main","isDraft":false,"updatedAt":"2026-02-24T00:00:02.600Z","syncedAt":"2026-02-24T00:00:02.700Z"}', NULL ), ( 'thread-1', 'github.com', 'pingdotgg/t3code', 42, 'https://github.com/pingdotgg/t3code/pull/42', 'manual', '2026-02-24T00:00:03.000Z', NULL, NULL ) `; yield* sql` INSERT INTO projection_threads ( thread_id, project_id, title, model_selection_json, runtime_mode, interaction_mode, branch, worktree_path, linked_pull_request_json, branch_pull_request_json, latest_turn_id, latest_user_message_at, pending_approval_count, pending_user_input_count, has_actionable_proposed_plan, pinned_at, pin_order_key, active_order_key, created_at, updated_at, deleted_at ) VALUES ( 'thread-1', 'project-1', 'Thread 1', '{"provider":"codex","model":"gpt-5-codex"}', 'full-access', 'default', NULL, NULL, '{"projectId":"project-1","repository":"pingdotgg/t3code","number":41,"url":"https://github.com/pingdotgg/t3code/pull/41"}', ${encodeThreadLinkedPullRequest(branchPullRequest)}, 'turn-1', '2026-02-24T00:00:04.000Z', 1, 0, 0, '2026-02-24T00:00:01.000Z', 'gm', 'hq', '2026-02-24T00:00:02.000Z', '2026-02-24T00:00:03.000Z', NULL ) `; yield* sql` INSERT INTO projection_thread_messages ( message_id, thread_id, turn_id, role, text, is_streaming, created_at, updated_at ) VALUES ( 'message-1', 'thread-1', 'turn-1', 'assistant', 'hello from projection', 0, '2026-02-24T00:00:04.000Z', '2026-02-24T00:00:05.000Z' ) `; yield* sql` INSERT INTO projection_thread_proposed_plans ( plan_id, thread_id, turn_id, plan_markdown, implemented_at, implementation_thread_id, created_at, updated_at ) VALUES ( 'plan-1', 'thread-1', 'turn-1', '# Ship it', '2026-02-24T00:00:05.500Z', 'thread-2', '2026-02-24T00:00:05.000Z', '2026-02-24T00:00:05.500Z' ) `; yield* sql` INSERT INTO projection_thread_activities ( activity_id, thread_id, turn_id, tone, kind, summary, payload_json, created_at ) VALUES ( 'activity-1', 'thread-1', 'turn-1', 'info', 'runtime.note', 'provider started', '{"stage":"start"}', '2026-02-24T00:00:06.000Z' ) `; yield* sql` INSERT INTO projection_thread_sessions ( thread_id, status, provider_name, provider_session_id, provider_thread_id, runtime_mode, active_turn_id, last_error, updated_at ) VALUES ( 'thread-1', 'running', 'codex', 'provider-session-1', 'provider-thread-1', 'approval-required', 'turn-1', NULL, '2026-02-24T00:00:07.000Z' ) `; yield* sql` INSERT INTO projection_turns ( thread_id, turn_id, pending_message_id, source_proposed_plan_thread_id, source_proposed_plan_id, assistant_message_id, state, requested_at, started_at, completed_at, checkpoint_turn_count, checkpoint_ref, checkpoint_status, checkpoint_files_json ) VALUES ( 'thread-1', 'turn-1', NULL, 'thread-1', 'plan-1', 'message-1', 'completed', '2026-02-24T00:00:08.000Z', '2026-02-24T00:00:08.000Z', '2026-02-24T00:00:08.000Z', 1, 'checkpoint-1', 'ready', '[{"path":"README.md","kind":"modified","additions":2,"deletions":1}]' ) `; let sequence = 5; for (const projector of Object.values(ORCHESTRATION_PROJECTOR_NAMES)) { yield* sql` INSERT INTO projection_state ( projector, last_applied_sequence, updated_at ) VALUES ( ${projector}, ${sequence}, '2026-02-24T00:00:09.000Z' ) `; sequence += 1; } const expectedPullRequests: ReadonlyArray<ThreadPullRequestLink> = [ { host: "github.com", repository: "pingdotgg/t3code", number: 41, url: "https://github.com/pingdotgg/t3code/pull/41", source: "created", linkedAt: "2026-02-24T00:00:02.500Z", snapshot: { state: "merged", title: "Groundwork", headBranch: "feat/groundwork", baseBranch: "main", isDraft: false, updatedAt: "2026-02-24T00:00:02.600Z", syncedAt: "2026-02-24T00:00:02.700Z", }, stack: null, }, { host: "github.com", repository: "pingdotgg/t3code", number: 42, url: "https://github.com/pingdotgg/t3code/pull/42", source: "manual", linkedAt: "2026-02-24T00:00:03.000Z", snapshot: null, stack: null, }, ]; const snapshot = yield* snapshotQuery.getSnapshot(); assert.equal(snapshot.snapshotSequence, 5); assert.equal(snapshot.updatedAt, "2026-02-24T00:00:09.000Z"); assert.deepEqual(snapshot.projects, [ { id: asProjectId("project-1"), title: "Project 1", workspaceRoot: "/tmp/project-1", repositoryIdentity: null, defaultModelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, autoPull: false, faviconPath: null, projectIcon: null, scripts: [ { id: "script-1", name: "Build", command: "bun run build", icon: "build", runOnWorktreeCreate: false, }, ], defaultThreadEnvMode: null, createdAt: "2026-02-24T00:00:00.000Z", updatedAt: "2026-02-24T00:00:01.000Z", deletedAt: null, }, ]); assert.deepEqual(snapshot.threads, [ { id: ThreadId.make("thread-1"), projectId: asProjectId("project-1"), title: "Thread 1", modelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, interactionMode: "default", runtimeMode: "full-access", branch: null, worktreePath: null, pullRequests: expectedPullRequests, branchPullRequest, latestTurn: { turnId: asTurnId("turn-1"), state: "completed", requestedAt: "2026-02-24T00:00:08.000Z", startedAt: "2026-02-24T00:00:08.000Z", completedAt: "2026-02-24T00:00:08.000Z", assistantMessageId: asMessageId("message-1"), sourceProposedPlan: { threadId: ThreadId.make("thread-1"), planId: "plan-1", }, }, createdAt: "2026-02-24T00:00:02.000Z", updatedAt: "2026-02-24T00:00:03.000Z", archivedAt: null, settledOverride: null, settledAt: null, unsettledAt: null, snoozedUntil: null, snoozedAt: null, pinnedAt: "2026-02-24T00:00:01.000Z", pinOrderKey: "gm", activeOrderKey: "hq", titleRegeneration: null, deletedAt: null, messages: [ { id: asMessageId("message-1"), role: "assistant", text: "hello from projection", turnId: asTurnId("turn-1"), streaming: false, createdAt: "2026-02-24T00:00:04.000Z", updatedAt: "2026-02-24T00:00:05.000Z", }, ], proposedPlans: [ { id: "plan-1", turnId: asTurnId("turn-1"), planMarkdown: "# Ship it", implementedAt: "2026-02-24T00:00:05.500Z", implementationThreadId: ThreadId.make("thread-2"), createdAt: "2026-02-24T00:00:05.000Z", updatedAt: "2026-02-24T00:00:05.500Z", }, ], activities: [ { id: asEventId("activity-1"), tone: "info", kind: "runtime.note", summary: "provider started", payload: { stage: "start" }, turnId: asTurnId("turn-1"), createdAt: "2026-02-24T00:00:06.000Z", }, ], checkpoints: [ { turnId: asTurnId("turn-1"), checkpointTurnCount: 1, checkpointRef: asCheckpointRef("checkpoint-1"), status: "ready", files: [{ path: "README.md", kind: "modified", additions: 2, deletions: 1 }], assistantMessageId: asMessageId("message-1"), completedAt: "2026-02-24T00:00:08.000Z", }, ], session: { threadId: ThreadId.make("thread-1"), status: "running", providerName: "codex", runtimeMode: "approval-required", activeTurnId: asTurnId("turn-1"), lastError: null, updatedAt: "2026-02-24T00:00:07.000Z", }, }, ]); const shellSnapshot = yield* snapshotQuery.getShellSnapshot(); assert.equal(shellSnapshot.snapshotSequence, 5); assert.deepEqual(shellSnapshot.projects, [ { id: asProjectId("project-1"), title: "Project 1", workspaceRoot: "/tmp/project-1", repositoryIdentity: null, defaultModelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", },Lines 1–500 of 3390. Load more
import { type AgentSessionImportSource, ChatAttachment, CheckpointRef, EventId, MessageId, ProjectId, ThreadId, type ThreadPullRequestLink, ThreadLinkedPullRequest, TurnId, ProviderInstanceId, } from "@t3tools/contracts"; import { assert, it } from "@effect/vitest"; import * as NodeServices from "@effect/platform-node/NodeServices"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; import * as SqlClient from "effect/unstable/sql/SqlClient"; import { SqlitePersistenceMemory } from "../../persistence/Layers/Sqlite.ts"; import * as RepositoryIdentityResolver from "../../project/RepositoryIdentityResolver.ts"; import { ORCHESTRATION_PROJECTOR_NAMES } from "./ProjectionPipeline.ts"; import { OrchestrationProjectionSnapshotQueryLive } from "./ProjectionSnapshotQuery.ts"; import * as ThreadBackgroundLiveness from "../ThreadBackgroundLiveness.ts"; import * as ThreadPlanProgress from "../ThreadPlanProgress.ts"; import { ProjectionSnapshotQuery } from "../Services/ProjectionSnapshotQuery.ts"; import { encodeThreadDetailPageCursor } from "../threadDetailCursor.ts"; import { projectThreadDetailSnapshot } from "../ActivityPayloadProjection.ts"; import { makeSqlStatementCounter } from "../../../integration/SqlStatementCounter.integration.ts"; const asProjectId = (value: string): ProjectId => ProjectId.make(value); const asTurnId = (value: string): TurnId => TurnId.make(value); const asMessageId = (value: string): MessageId => MessageId.make(value); const asEventId = (value: string): EventId => EventId.make(value); const asCheckpointRef = (value: string): CheckpointRef => CheckpointRef.make(value); const encodeChatAttachments = Schema.encodeEffect( Schema.fromJsonString(Schema.Array(ChatAttachment)), ); const encodeThreadLinkedPullRequest = Schema.encodeSync( Schema.fromJsonString(ThreadLinkedPullRequest), ); const projectionSnapshotLayer = it.layer( OrchestrationProjectionSnapshotQueryLive.pipe( Layer.provide(ThreadBackgroundLiveness.layer), Layer.provide(ThreadPlanProgress.layer), Layer.provideMerge(RepositoryIdentityResolver.layer), Layer.provideMerge(SqlitePersistenceMemory), Layer.provideMerge(NodeServices.layer), ), ); projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { it.effect("hydrates read model from projection tables and computes snapshot sequence", () => Effect.gen(function* () { const snapshotQuery = yield* ProjectionSnapshotQuery; const sql = yield* SqlClient.SqlClient; const branchPullRequest = { projectId: asProjectId("project-1"), repository: "pingdotgg/t3code", number: 43, url: "https://github.com/pingdotgg/t3code/pull/43", }; yield* sql`DELETE FROM projection_projects`; yield* sql`DELETE FROM projection_state`; yield* sql`DELETE FROM projection_thread_proposed_plans`; yield* sql`DELETE FROM projection_thread_pull_requests`; yield* sql`DELETE FROM projection_turns`; yield* sql` INSERT INTO projection_projects ( project_id, title, workspace_root, default_model_selection_json, scripts_json, created_at, updated_at, deleted_at ) VALUES ( 'project-1', 'Project 1', '/tmp/project-1', '{"provider":"codex","model":"gpt-5-codex"}', '[{"id":"script-1","name":"Build","command":"bun run build","icon":"build","runOnWorktreeCreate":false}]', '2026-02-24T00:00:00.000Z', '2026-02-24T00:00:01.000Z', NULL ) `; // A merged link plus a newer open one: the multi-link projection must // resolve to the open pull request, not the stale JSON column below. yield* sql` INSERT INTO projection_thread_pull_requests ( thread_id, host, repository, number, url, source, linked_at, snapshot_json, stack_json ) VALUES ( 'thread-1', 'github.com', 'pingdotgg/t3code', 41, 'https://github.com/pingdotgg/t3code/pull/41', 'created', '2026-02-24T00:00:02.500Z', '{"state":"merged","title":"Groundwork","headBranch":"feat/groundwork","baseBranch":"main","isDraft":false,"updatedAt":"2026-02-24T00:00:02.600Z","syncedAt":"2026-02-24T00:00:02.700Z"}', NULL ), ( 'thread-1', 'github.com', 'pingdotgg/t3code', 42, 'https://github.com/pingdotgg/t3code/pull/42', 'manual', '2026-02-24T00:00:03.000Z', NULL, NULL ) `; yield* sql` INSERT INTO projection_threads ( thread_id, project_id, title, model_selection_json, runtime_mode, interaction_mode, branch, worktree_path, linked_pull_request_json, branch_pull_request_json, latest_turn_id, latest_user_message_at, pending_approval_count, pending_user_input_count, has_actionable_proposed_plan, pinned_at, pin_order_key, active_order_key, created_at, updated_at, deleted_at ) VALUES ( 'thread-1', 'project-1', 'Thread 1', '{"provider":"codex","model":"gpt-5-codex"}', 'full-access', 'default', NULL, NULL, '{"projectId":"project-1","repository":"pingdotgg/t3code","number":41,"url":"https://github.com/pingdotgg/t3code/pull/41"}', ${encodeThreadLinkedPullRequest(branchPullRequest)}, 'turn-1', '2026-02-24T00:00:04.000Z', 1, 0, 0, '2026-02-24T00:00:01.000Z', 'gm', 'hq', '2026-02-24T00:00:02.000Z', '2026-02-24T00:00:03.000Z', NULL ) `; yield* sql` INSERT INTO projection_thread_messages ( message_id, thread_id, turn_id, role, text, is_streaming, created_at, updated_at ) VALUES ( 'message-1', 'thread-1', 'turn-1', 'assistant', 'hello from projection', 0, '2026-02-24T00:00:04.000Z', '2026-02-24T00:00:05.000Z' ) `; yield* sql` INSERT INTO projection_thread_proposed_plans ( plan_id, thread_id, turn_id, plan_markdown, implemented_at, implementation_thread_id, created_at, updated_at ) VALUES ( 'plan-1', 'thread-1', 'turn-1', '# Ship it', '2026-02-24T00:00:05.500Z', 'thread-2', '2026-02-24T00:00:05.000Z', '2026-02-24T00:00:05.500Z' ) `; yield* sql` INSERT INTO projection_thread_activities ( activity_id, thread_id, turn_id, tone, kind, summary, payload_json, created_at ) VALUES ( 'activity-1', 'thread-1', 'turn-1', 'info', 'runtime.note', 'provider started', '{"stage":"start"}', '2026-02-24T00:00:06.000Z' ) `; yield* sql` INSERT INTO projection_thread_sessions ( thread_id, status, provider_name, provider_session_id, provider_thread_id, runtime_mode, active_turn_id, last_error, updated_at ) VALUES ( 'thread-1', 'running', 'codex', 'provider-session-1', 'provider-thread-1', 'approval-required', 'turn-1', NULL, '2026-02-24T00:00:07.000Z' ) `; yield* sql` INSERT INTO projection_turns ( thread_id, turn_id, pending_message_id, source_proposed_plan_thread_id, source_proposed_plan_id, assistant_message_id, state, requested_at, started_at, completed_at, checkpoint_turn_count, checkpoint_ref, checkpoint_status, checkpoint_files_json ) VALUES ( 'thread-1', 'turn-1', NULL, 'thread-1', 'plan-1', 'message-1', 'completed', '2026-02-24T00:00:08.000Z', '2026-02-24T00:00:08.000Z', '2026-02-24T00:00:08.000Z', 1, 'checkpoint-1', 'ready', '[{"path":"README.md","kind":"modified","additions":2,"deletions":1}]' ) `; let sequence = 5; for (const projector of Object.values(ORCHESTRATION_PROJECTOR_NAMES)) { yield* sql` INSERT INTO projection_state ( projector, last_applied_sequence, updated_at ) VALUES ( ${projector}, ${sequence}, '2026-02-24T00:00:09.000Z' ) `; sequence += 1; } const expectedPullRequests: ReadonlyArray<ThreadPullRequestLink> = [ { host: "github.com", repository: "pingdotgg/t3code", number: 41, url: "https://github.com/pingdotgg/t3code/pull/41", source: "created", linkedAt: "2026-02-24T00:00:02.500Z", snapshot: { state: "merged", title: "Groundwork", headBranch: "feat/groundwork", baseBranch: "main", isDraft: false, updatedAt: "2026-02-24T00:00:02.600Z", syncedAt: "2026-02-24T00:00:02.700Z", }, stack: null, }, { host: "github.com", repository: "pingdotgg/t3code", number: 42, url: "https://github.com/pingdotgg/t3code/pull/42", source: "manual", linkedAt: "2026-02-24T00:00:03.000Z", snapshot: null, stack: null, }, ]; const snapshot = yield* snapshotQuery.getSnapshot(); assert.equal(snapshot.snapshotSequence, 5); assert.equal(snapshot.updatedAt, "2026-02-24T00:00:09.000Z"); assert.deepEqual(snapshot.projects, [ { id: asProjectId("project-1"), title: "Project 1", workspaceRoot: "/tmp/project-1", repositoryIdentity: null, defaultModelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, autoPull: false, faviconPath: null, projectIcon: null, scripts: [ { id: "script-1", name: "Build", command: "bun run build", icon: "build", runOnWorktreeCreate: false, }, ], defaultThreadEnvMode: null, createdAt: "2026-02-24T00:00:00.000Z", updatedAt: "2026-02-24T00:00:01.000Z", deletedAt: null, }, ]); assert.deepEqual(snapshot.threads, [ { id: ThreadId.make("thread-1"), projectId: asProjectId("project-1"), title: "Thread 1", modelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", }, interactionMode: "default", runtimeMode: "full-access", branch: null, worktreePath: null, pullRequests: expectedPullRequests, branchPullRequest, latestTurn: { turnId: asTurnId("turn-1"), state: "completed", requestedAt: "2026-02-24T00:00:08.000Z", startedAt: "2026-02-24T00:00:08.000Z", completedAt: "2026-02-24T00:00:08.000Z", assistantMessageId: asMessageId("message-1"), sourceProposedPlan: { threadId: ThreadId.make("thread-1"), planId: "plan-1", }, }, createdAt: "2026-02-24T00:00:02.000Z", updatedAt: "2026-02-24T00:00:03.000Z", archivedAt: null, settledOverride: null, settledAt: null, unsettledAt: null, snoozedUntil: null, snoozedAt: null, pinnedAt: "2026-02-24T00:00:01.000Z", pinOrderKey: "gm", activeOrderKey: "hq", titleRegeneration: null, deletedAt: null, messages: [ { id: asMessageId("message-1"), role: "assistant", text: "hello from projection", turnId: asTurnId("turn-1"), streaming: false, createdAt: "2026-02-24T00:00:04.000Z", updatedAt: "2026-02-24T00:00:05.000Z", }, ], proposedPlans: [ { id: "plan-1", turnId: asTurnId("turn-1"), planMarkdown: "# Ship it", implementedAt: "2026-02-24T00:00:05.500Z", implementationThreadId: ThreadId.make("thread-2"), createdAt: "2026-02-24T00:00:05.000Z", updatedAt: "2026-02-24T00:00:05.500Z", }, ], activities: [ { id: asEventId("activity-1"), tone: "info", kind: "runtime.note", summary: "provider started", payload: { stage: "start" }, turnId: asTurnId("turn-1"), createdAt: "2026-02-24T00:00:06.000Z", }, ], checkpoints: [ { turnId: asTurnId("turn-1"), checkpointTurnCount: 1, checkpointRef: asCheckpointRef("checkpoint-1"), status: "ready", files: [{ path: "README.md", kind: "modified", additions: 2, deletions: 1 }], assistantMessageId: asMessageId("message-1"), completedAt: "2026-02-24T00:00:08.000Z", }, ], session: { threadId: ThreadId.make("thread-1"), status: "running", providerName: "codex", runtimeMode: "approval-required", activeTurnId: asTurnId("turn-1"), lastError: null, updatedAt: "2026-02-24T00:00:07.000Z", }, }, ]); const shellSnapshot = yield* snapshotQuery.getShellSnapshot(); assert.equal(shellSnapshot.snapshotSequence, 5); assert.deepEqual(shellSnapshot.projects, [ { id: asProjectId("project-1"), title: "Project 1", workspaceRoot: "/tmp/project-1", repositoryIdentity: null, defaultModelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5-codex", },