authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-26 19:23:26-08:00
committergravatar for jmarminge@gmail.comJulius Marminge <jmarminge@gmail.com> 2026-02-26 19:27:08-08:00
log9c4095aaaa31c5628d40026cbddf094c0f85146d
treefb5dcc2d84b2da9f247308cbdc804ecbe954aedb
parent961df8597c4c8149febbc95d0ab52f895ca7ff94

Fix Effect type warnings to pass typecheck

- Use generic type parameter for stream errors instead of unknown - Type ServerShape errors as ServerLifecycleError instead of unknown - Add error mapping for autoBootstrapProject and httpServerListen - Type makeServerProviderLayer with ProviderUnsupportedError - Use Effect.try with decodeUnknownSync in projector to avoid unknown requirements - Fix test layer types from any/unknown to never Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

6 files changed, 41 insertions(+), 29 deletions(-)

apps/server/src/git/Layers/CodexTextGeneration.ts+2-2
...@@ -129,9 +129,9 @@ const makeCodexTextGeneration = Effect.gen(function* () {...@@ -129,9 +129,9 @@ const makeCodexTextGeneration = Effect.gen(function* () {
129 const path = yield* Path.Path;129 const path = yield* Path.Path;
130 const commandSpawner = yield* ChildProcessSpawner.ChildProcessSpawner;130 const commandSpawner = yield* ChildProcessSpawner.ChildProcessSpawner;
131131
132 const readStreamAsString = (132 const readStreamAsString = <E>(
133 operation: string,133 operation: string,
134 stream: Stream.Stream<Uint8Array, unknown>,134 stream: Stream.Stream<Uint8Array, E>,
135 ): Effect.Effect<string, TextGenerationError> =>135 ): Effect.Effect<string, TextGenerationError> =>
136 Effect.gen(function* () {136 Effect.gen(function* () {
137 let text = "";137 let text = "";
apps/server/src/git/Layers/GitService.ts+2-2
...@@ -39,9 +39,9 @@ function toGitCommandError(...@@ -39,9 +39,9 @@ function toGitCommandError(
39 });39 });
40}40}
4141
42const collectOutput = Effect.fn(function* (42const collectOutput = Effect.fn(function* <E>(
43 input: Pick<ExecuteGitInput, "operation" | "cwd" | "args">,43 input: Pick<ExecuteGitInput, "operation" | "cwd" | "args">,
44 stream: Stream.Stream<Uint8Array, unknown>,44 stream: Stream.Stream<Uint8Array, E>,
45 maxOutputBytes: number,45 maxOutputBytes: number,
46): Effect.fn.Return<string, GitCommandError> {46): Effect.fn.Return<string, GitCommandError> {
47 const decoder = new TextDecoder();47 const decoder = new TextDecoder();
apps/server/src/orchestration/projector.ts+6-3
...@@ -40,9 +40,12 @@ function decodeForEvent<A>(...@@ -40,9 +40,12 @@ function decodeForEvent<A>(
40 eventType: OrchestrationEvent["type"],40 eventType: OrchestrationEvent["type"],
41 field: string,41 field: string,
42): Effect.Effect<A, OrchestrationProjectorDecodeError> {42): Effect.Effect<A, OrchestrationProjectorDecodeError> {
43 return Schema.decodeUnknownEffect(schema)(value).pipe(43 return Effect.try({
44 Effect.mapError(toProjectorDecodeError(`${eventType}:${field}`)),44 // eslint-disable-next-line @typescript-eslint/no-explicit-any
45 ) as Effect.Effect<A, OrchestrationProjectorDecodeError>;45 try: () => Schema.decodeUnknownSync(schema as any)(value) as A,
46 catch: (error) =>
47 toProjectorDecodeError(`${eventType}:${field}`)(error as Schema.SchemaError),
48 });
46}49}
4750
48function retainThreadMessagesAfterRevert(51function retainThreadMessagesAfterRevert(
apps/server/src/serverLayers.ts+2-1
...@@ -17,6 +17,7 @@ import { ProviderCommandReactorLive } from "./orchestration/Layers/ProviderComma...@@ -17,6 +17,7 @@ import { ProviderCommandReactorLive } from "./orchestration/Layers/ProviderComma
17import { OrchestrationProjectionPipelineLive } from "./orchestration/Layers/ProjectionPipeline";17import { OrchestrationProjectionPipelineLive } from "./orchestration/Layers/ProjectionPipeline";
18import { OrchestrationProjectionSnapshotQueryLive } from "./orchestration/Layers/ProjectionSnapshotQuery";18import { OrchestrationProjectionSnapshotQueryLive } from "./orchestration/Layers/ProjectionSnapshotQuery";
19import { ProviderRuntimeIngestionLive } from "./orchestration/Layers/ProviderRuntimeIngestion";19import { ProviderRuntimeIngestionLive } from "./orchestration/Layers/ProviderRuntimeIngestion";
20import { ProviderUnsupportedError } from "./provider/Errors";
20import { makeCodexAdapterLive } from "./provider/Layers/CodexAdapter";21import { makeCodexAdapterLive } from "./provider/Layers/CodexAdapter";
21import { ProviderAdapterRegistryLive } from "./provider/Layers/ProviderAdapterRegistry";22import { ProviderAdapterRegistryLive } from "./provider/Layers/ProviderAdapterRegistry";
22import { makeProviderServiceLive } from "./provider/Layers/ProviderService";23import { makeProviderServiceLive } from "./provider/Layers/ProviderService";
...@@ -35,7 +36,7 @@ import { NodePtyAdapterLive } from "./terminal/Layers/NodePTY";...@@ -35,7 +36,7 @@ import { NodePtyAdapterLive } from "./terminal/Layers/NodePTY";
3536
36export function makeServerProviderLayer(): Layer.Layer<37export function makeServerProviderLayer(): Layer.Layer<
37 ProviderService,38 ProviderService,
38 unknown,39 ProviderUnsupportedError,
39 SqlClient.SqlClient | ServerConfig40 SqlClient.SqlClient | ServerConfig
40> {41> {
41 return Effect.gen(function* () {42 return Effect.gen(function* () {
apps/server/src/wsServer.test.ts+2-2
...@@ -323,14 +323,14 @@ describe("WebSocket Server", () => {...@@ -323,14 +323,14 @@ describe("WebSocket Server", () => {
323323
324 async function createTestServer(324 async function createTestServer(
325 options: {325 options: {
326 persistenceLayer?: Layer.Layer<SqlClient.SqlClient, any>;326 persistenceLayer?: Layer.Layer<SqlClient.SqlClient, never>;
327 cwd?: string;327 cwd?: string;
328 autoBootstrapProjectFromCwd?: boolean;328 autoBootstrapProjectFromCwd?: boolean;
329 logWebSocketEvents?: boolean;329 logWebSocketEvents?: boolean;
330 devUrl?: string;330 devUrl?: string;
331 authToken?: string;331 authToken?: string;
332 stateDir?: string;332 stateDir?: string;
333 providerLayer?: Layer.Layer<ProviderService, unknown>;333 providerLayer?: Layer.Layer<ProviderService, never>;
334 open?: OpenShape;334 open?: OpenShape;
335 gitManager?: GitManagerShape;335 gitManager?: GitManagerShape;
336 gitCore?: Pick<GitCoreShape, "listBranches" | "initRepo" | "pullCurrentBranch">;336 gitCore?: Pick<GitCoreShape, "listBranches" | "initRepo" | "pullCurrentBranch">;
apps/server/src/wsServer.ts+27-19
...@@ -66,14 +66,14 @@ export interface ServerShape {...@@ -66,14 +66,14 @@ export interface ServerShape {
66 */66 */
67 readonly start: Effect.Effect<67 readonly start: Effect.Effect<
68 http.Server,68 http.Server,
69 unknown,69 ServerLifecycleError,
70 Scope.Scope | ServerRuntimeServices | ServerConfig70 Scope.Scope | ServerRuntimeServices | ServerConfig
71 >;71 >;
7272
73 /**73 /**
74 * Wait for process shutdown signals.74 * Wait for process shutdown signals.
75 */75 */
76 readonly stopSignal: Effect.Effect<unknown, never>;76 readonly stopSignal: Effect.Effect<void, never>;
77}77}
7878
79/**79/**
...@@ -165,7 +165,7 @@ class RouteRequestError extends Schema.TaggedErrorClass<RouteRequestError>()("Ro...@@ -165,7 +165,7 @@ class RouteRequestError extends Schema.TaggedErrorClass<RouteRequestError>()("Ro
165165
166export const createServer = Effect.fn(function* (): Effect.fn.Return<166export const createServer = Effect.fn(function* (): Effect.fn.Return<
167 http.Server,167 http.Server,
168 unknown, // TODO: This should not be unknown168 ServerLifecycleError,
169 Scope.Scope | ServerRuntimeServices | ServerConfig169 Scope.Scope | ServerRuntimeServices | ServerConfig
170> {170> {
171 const serverConfig = yield* ServerConfig;171 const serverConfig = yield* ServerConfig;
...@@ -338,21 +338,27 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<...@@ -338,21 +338,27 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<
338 yield* Scope.provide(orchestrationReactor.start, subscriptionsScope);338 yield* Scope.provide(orchestrationReactor.start, subscriptionsScope);
339339
340 if (autoBootstrapProjectFromCwd) {340 if (autoBootstrapProjectFromCwd) {
341 const snapshot = yield* projectionReadModelQuery.getSnapshot();341 yield* Effect.gen(function* () {
342 const existing = snapshot.projects.find((project) => project.workspaceRoot === cwd);342 const snapshot = yield* projectionReadModelQuery.getSnapshot();
343 if (!existing) {343 const existing = snapshot.projects.find((project) => project.workspaceRoot === cwd);
344 const createdAt = new Date().toISOString();344 if (!existing) {
345 const projectName = path.basename(cwd) || "project";345 const createdAt = new Date().toISOString();
346 yield* orchestrationEngine.dispatch({346 const projectName = path.basename(cwd) || "project";
347 type: "project.create",347 yield* orchestrationEngine.dispatch({
348 commandId: CommandId.makeUnsafe(crypto.randomUUID()),348 type: "project.create",
349 projectId: ProjectId.makeUnsafe(crypto.randomUUID()),349 commandId: CommandId.makeUnsafe(crypto.randomUUID()),
350 title: projectName,350 projectId: ProjectId.makeUnsafe(crypto.randomUUID()),
351 workspaceRoot: cwd,351 title: projectName,
352 defaultModel: "gpt-5-codex",352 workspaceRoot: cwd,
353 createdAt,353 defaultModel: "gpt-5-codex",
354 });354 createdAt,
355 }355 });
356 }
357 }).pipe(
358 Effect.mapError(
359 (cause) => new ServerLifecycleError({ operation: "autoBootstrapProject", cause }),
360 ),
361 );
356 }362 }
357363
358 const routeRequest = Effect.fnUntraced(function* (request: WebSocketRequest) {364 const routeRequest = Effect.fnUntraced(function* (request: WebSocketRequest) {
...@@ -618,7 +624,9 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<...@@ -618,7 +624,9 @@ export const createServer = Effect.fn(function* (): Effect.fn.Return<
618 );624 );
619 yield* Effect.addFinalizer(() => Effect.sync(() => unsubscribeTerminalEvents()));625 yield* Effect.addFinalizer(() => Effect.sync(() => unsubscribeTerminalEvents()));
620626
621 yield* NodeHttpServer.make(() => httpServer, listenOptions);627 yield* NodeHttpServer.make(() => httpServer, listenOptions).pipe(
628 Effect.mapError((cause) => new ServerLifecycleError({ operation: "httpServerListen", cause })),
629 );
622630
623 yield* Effect.addFinalizer(() =>631 yield* Effect.addFinalizer(() =>
624 Effect.all([632 Effect.all([