import * as NodeServices from "@effect/platform-node/NodeServices"; import { DEFAULT_MODEL, ProjectId, ProviderInstanceId, ThreadId } from "@t3tools/contracts"; import { assert, it } from "@effect/vitest"; import * as Crypto from "effect/Crypto"; import * as Deferred from "effect/Deferred"; import * as Effect from "effect/Effect"; import * as Fiber from "effect/Fiber"; import * as Option from "effect/Option"; import * as PlatformError from "effect/PlatformError"; import * as Ref from "effect/Ref"; import * as Stream from "effect/Stream"; import * as ServerConfig from "./config.ts"; import * as OrchestrationEngine from "./orchestration/Services/OrchestrationEngine.ts"; import * as ProjectionSnapshotQuery from "./orchestration/Services/ProjectionSnapshotQuery.ts"; import * as AnalyticsService from "./telemetry/AnalyticsService.ts"; import * as ServerRuntimeStartup from "./serverRuntimeStartup.ts"; import * as GitVcsDriver from "./vcs/GitVcsDriver.ts"; it("uses the canonical Codex default for the auto-bootstrapped welcome thread", () => { assert.deepStrictEqual(ServerRuntimeStartup.getAutoBootstrapThreadModelSelection(), { instanceId: ProviderInstanceId.make("codex"), model: DEFAULT_MODEL, }); }); it.effect("automatic pull only updates enabled, behind, clean default-branch checkouts", () => Effect.gen(function* () { const pulled: string[] = []; const git = { statusDetails: (cwd: string) => Effect.succeed({ isRepo: true, isDefaultBranch: cwd !== "/feature", hasUpstream: true, hasWorkingTreeChanges: cwd === "/dirty", aheadCount: cwd === "/ahead" ? 1 : 0, behindCount: cwd === "/current" ? 0 : 1, } as never), pullCurrentBranch: (cwd: string) => Effect.sync(() => { pulled.push(cwd); return { status: "pulled" as const, refName: "main", upstreamRef: "origin/main", }; }), } as unknown as GitVcsDriver.GitVcsDriver["Service"]; const project = (workspaceRoot: string, autoPull = true) => ({ workspaceRoot, autoPull }) as never; yield* ServerRuntimeStartup.autoPullProjects([ project("/clean"), project("/current"), project("/dirty"), project("/ahead"), project("/feature"), project("/disabled", false), ]).pipe(Effect.provideService(GitVcsDriver.GitVcsDriver, git)); assert.deepStrictEqual(pulled, ["/clean"]); }), ); it.effect("enqueueCommand waits for readiness and then drains queued work", () => Effect.scoped( Effect.gen(function* () { const executionCount = yield* Ref.make(0); const commandGate = yield* ServerRuntimeStartup.makeCommandGate; const queuedCommandFiber = yield* commandGate .enqueueCommand(Ref.updateAndGet(executionCount, (count) => count + 1)) .pipe(Effect.forkScoped); yield* Effect.yieldNow; assert.equal(yield* Ref.get(executionCount), 0); yield* commandGate.signalCommandReady; const result = yield* Fiber.join(queuedCommandFiber); assert.equal(result, 1); assert.equal(yield* Ref.get(executionCount), 1); }), ), ); it.effect("enqueueCommand fails queued work when readiness fails", () => Effect.scoped( Effect.gen(function* () { const commandGate = yield* ServerRuntimeStartup.makeCommandGate; const failure = yield* Deferred.make(); const queuedCommandFiber = yield* commandGate .enqueueCommand(Deferred.await(failure).pipe(Effect.as("should-not-run"))) .pipe(Effect.forkScoped); yield* commandGate.failCommandReady( new ServerRuntimeStartup.ServerRuntimeStartupError({ mode: "web", host: "127.0.0.1", port: 3773, cause: new Error("test startup failure"), }), ); const error = yield* Effect.flip(Fiber.join(queuedCommandFiber)); assert.equal(error.message, "Server runtime startup failed before command readiness."); }), ), ); it.effect("launchStartupHeartbeat does not block the caller while counts are loading", () => Effect.scoped( Effect.gen(function* () { const releaseCounts = yield* Deferred.make(); const countsStarted = yield* Deferred.make(); yield* ServerRuntimeStartup.launchStartupHeartbeat.pipe( Effect.provideService(ProjectionSnapshotQuery.ProjectionSnapshotQuery, { getCommandReadModel: () => Effect.die("unused"), getSnapshot: () => Effect.die("unused"), getShellSnapshot: () => Effect.die("unused"), getArchivedShellSnapshot: () => Effect.die("unused"), getSnapshotSequence: () => Effect.die("unused"), getEventReplayStats: () => Effect.die("unused"), getCounts: () => Deferred.succeed(countsStarted, undefined).pipe( Effect.andThen(Deferred.await(releaseCounts)), Effect.as({ projectCount: 2, threadCount: 3, }), ), getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()), getProjectShellById: () => Effect.succeed(Option.none()), getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()), getThreadCheckpointContext: () => Effect.succeed(Option.none()), getFullThreadDiffContext: () => Effect.succeed(Option.none()), getThreadShellById: () => Effect.succeed(Option.none()), getThreadDetailById: () => Effect.succeed(Option.none()), getThreadDetailSnapshot: () => Effect.succeed(Option.none()), searchThreads: () => Effect.succeed({ matches: [] }), }), Effect.provideService(AnalyticsService.AnalyticsService, { record: () => Effect.void, flush: Effect.void, }), ); // The heartbeat is forked, so the caller is already back here while // getCounts is still parked. Awaiting countsStarted proves the forked // work really ran; releaseCounts staying incomplete proves the caller // never waited for it. yield* Deferred.await(countsStarted); assert.equal(yield* Deferred.isDone(releaseCounts), false); }), ), ); it.effect("resolveWelcomeBase derives cwd and project name from server config", () => Effect.gen(function* () { const welcome = yield* ServerRuntimeStartup.resolveWelcomeBase.pipe( Effect.provideService(ServerConfig.ServerConfig, { cwd: "/tmp/startup-project", } as never), ); assert.deepStrictEqual(welcome, { cwd: "/tmp/startup-project", projectName: "startup-project", }); }), ); it.effect("resolveAutoBootstrapWelcomeTargets returns existing project and thread ids", () => { const bootstrapProjectId = ProjectId.make("project-startup-bootstrap"); const bootstrapThreadId = ThreadId.make("thread-startup-bootstrap"); return Effect.gen(function* () { const dispatchCalls = yield* Ref.make>([]); const targets = yield* ServerRuntimeStartup.resolveAutoBootstrapWelcomeTargets.pipe( Effect.provideService(ServerConfig.ServerConfig, { cwd: "/tmp/startup-project", autoBootstrapProjectFromCwd: true, } as never), Effect.provideService(ProjectionSnapshotQuery.ProjectionSnapshotQuery, { getCommandReadModel: () => Effect.die("unused"), getSnapshot: () => Effect.die("unused"), getShellSnapshot: () => Effect.die("unused"), getArchivedShellSnapshot: () => Effect.die("unused"), getSnapshotSequence: () => Effect.die("unused"), getCounts: () => Effect.die("unused"), getEventReplayStats: () => Effect.die("unused"), getActiveProjectByWorkspaceRoot: () => Effect.succeed( Option.some({ id: bootstrapProjectId, title: "Startup Project", workspaceRoot: "/tmp/startup-project", defaultModelSelection: ServerRuntimeStartup.getAutoBootstrapThreadModelSelection(), scripts: [], createdAt: "2026-01-01T00:00:00.000Z", updatedAt: "2026-01-01T00:00:00.000Z", deletedAt: null, }), ), getProjectShellById: () => Effect.die("unused"), getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.some(bootstrapThreadId)), getThreadCheckpointContext: () => Effect.succeed(Option.none()), getFullThreadDiffContext: () => Effect.succeed(Option.none()), getThreadShellById: () => Effect.die("unused"), getThreadDetailById: () => Effect.die("unused"), getThreadDetailSnapshot: () => Effect.die("unused"), searchThreads: () => Effect.succeed({ matches: [] }), }), Effect.provideService(OrchestrationEngine.OrchestrationEngineService, { readEvents: () => Stream.empty, dispatch: (command) => Ref.update(dispatchCalls, (calls) => [...calls, command.type]).pipe( Effect.as({ sequence: 1 }), ), streamDomainEvents: Stream.empty, subscribeDomainEvents: Effect.succeed(Stream.empty), latestSequence: Effect.succeed(0), } satisfies OrchestrationEngine.OrchestrationEngineService["Service"]), Effect.provide(NodeServices.layer), ); assert.deepStrictEqual(targets, { bootstrapProjectId, bootstrapThreadId, }); assert.deepStrictEqual(yield* Ref.get(dispatchCalls), []); }); }); it.effect("resolveAutoBootstrapWelcomeTargets creates a project and thread when missing", () => Effect.gen(function* () { const dispatchCalls = yield* Ref.make< ReadonlyArray<{ readonly type: string; readonly defaultModelSelection?: unknown; readonly modelSelection?: unknown; }> >([]); const targets = yield* ServerRuntimeStartup.resolveAutoBootstrapWelcomeTargets.pipe( Effect.provideService(ServerConfig.ServerConfig, { cwd: "/tmp/startup-project", autoBootstrapProjectFromCwd: true, } as never), Effect.provideService(ProjectionSnapshotQuery.ProjectionSnapshotQuery, { getCommandReadModel: () => Effect.die("unused"), getSnapshot: () => Effect.die("unused"), getShellSnapshot: () => Effect.die("unused"), getArchivedShellSnapshot: () => Effect.die("unused"), getSnapshotSequence: () => Effect.die("unused"), getCounts: () => Effect.die("unused"), getEventReplayStats: () => Effect.die("unused"), getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()), getProjectShellById: () => Effect.die("unused"), getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()), getThreadCheckpointContext: () => Effect.succeed(Option.none()), getFullThreadDiffContext: () => Effect.succeed(Option.none()), getThreadShellById: () => Effect.die("unused"), getThreadDetailById: () => Effect.die("unused"), getThreadDetailSnapshot: () => Effect.die("unused"), searchThreads: () => Effect.succeed({ matches: [] }), }), Effect.provideService(OrchestrationEngine.OrchestrationEngineService, { readEvents: () => Stream.empty, dispatch: (command) => Ref.update(dispatchCalls, (calls) => [...calls, command]).pipe( Effect.as({ sequence: 1 }), ), streamDomainEvents: Stream.empty, subscribeDomainEvents: Effect.succeed(Stream.empty), latestSequence: Effect.succeed(0), } satisfies OrchestrationEngine.OrchestrationEngineService["Service"]), Effect.provide(NodeServices.layer), ); assert.equal(typeof targets.bootstrapProjectId, "string"); assert.equal(typeof targets.bootstrapThreadId, "string"); const commands = yield* Ref.get(dispatchCalls); assert.deepStrictEqual( commands.map((command) => command.type), ["project.create", "thread.create"], ); assert.equal("defaultModelSelection" in commands[0]!, false); assert.deepStrictEqual( commands[1]?.modelSelection, ServerRuntimeStartup.getAutoBootstrapThreadModelSelection(), ); }), ); it.effect("resolveAutoBootstrapWelcomeTargets preserves typed UUID generation failures", () => Effect.gen(function* () { const crypto = yield* Crypto.Crypto; const uuidError = PlatformError.systemError({ _tag: "Unknown", module: "Crypto", method: "randomUUIDv4", description: "UUID generation unavailable", }); const dispatchCalls = yield* Ref.make>([]); const error = yield* ServerRuntimeStartup.resolveAutoBootstrapWelcomeTargets.pipe( Effect.provideService(ServerConfig.ServerConfig, { cwd: "/tmp/startup-project", autoBootstrapProjectFromCwd: true, } as never), Effect.provideService(ProjectionSnapshotQuery.ProjectionSnapshotQuery, { getCommandReadModel: () => Effect.die("unused"), getSnapshot: () => Effect.die("unused"), getShellSnapshot: () => Effect.die("unused"), getArchivedShellSnapshot: () => Effect.die("unused"), getSnapshotSequence: () => Effect.die("unused"), getCounts: () => Effect.die("unused"), getEventReplayStats: () => Effect.die("unused"), getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()), getProjectShellById: () => Effect.die("unused"), getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()), getThreadCheckpointContext: () => Effect.succeed(Option.none()), getFullThreadDiffContext: () => Effect.succeed(Option.none()), getThreadShellById: () => Effect.die("unused"), getThreadDetailById: () => Effect.die("unused"), getThreadDetailSnapshot: () => Effect.die("unused"), searchThreads: () => Effect.succeed({ matches: [] }), }), Effect.provideService(OrchestrationEngine.OrchestrationEngineService, { readEvents: () => Stream.empty, dispatch: (command) => Ref.update(dispatchCalls, (calls) => [...calls, command.type]).pipe( Effect.as({ sequence: 1 }), ), streamDomainEvents: Stream.empty, subscribeDomainEvents: Effect.succeed(Stream.empty), latestSequence: Effect.succeed(0), } satisfies OrchestrationEngine.OrchestrationEngineService["Service"]), Effect.provideService(Crypto.Crypto, { ...crypto, randomUUIDv4: Effect.fail(uuidError), }), Effect.flip, ); assert.strictEqual(error, uuidError); assert.deepStrictEqual(yield* Ref.get(dispatchCalls), []); }).pipe(Effect.provide(NodeServices.layer)), );