Skip to content

Commit d0e5b88

Browse files
feat(server): add cursor and opencode providers
1 parent 7ee2aec commit d0e5b88

232 files changed

Lines changed: 26405 additions & 1874 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"dev:electron": "bun run scripts/dev-electron.mjs",
1010
"build": "tsdown",
1111
"start": "bun run scripts/start-electron.mjs",
12-
"typecheck": "tsc --noEmit",
12+
"typecheck": "tsgo --noEmit",
1313
"test": "vitest run --passWithNoTests",
1414
"smoke-test": "node scripts/smoke-test.mjs"
1515
},

apps/desktop/src/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import type {
2525
import { autoUpdater } from "electron-updater";
2626

2727
import type { ContextMenuItem } from "@t3tools/contracts";
28-
import { NetService } from "@t3tools/shared/Net";
28+
import { layer as NetServiceLayer, NetService } from "@t3tools/shared/Net";
2929
import { RotatingFileSink } from "@t3tools/shared/logging";
3030
import { showDesktopConfirmDialog } from "./confirmDialog";
3131
import { syncShellEnvironment } from "./syncShellEnvironment";
@@ -1340,7 +1340,7 @@ async function bootstrap(): Promise<void> {
13401340
writeDesktopLogHeader("bootstrap start");
13411341
backendPort = await Effect.service(NetService).pipe(
13421342
Effect.flatMap((net) => net.reserveLoopbackPort()),
1343-
Effect.provide(NetService.layer),
1343+
Effect.provide(NetServiceLayer),
13441344
Effect.runPromise,
13451345
);
13461346
writeDesktopLogHeader(`reserved backend port via NetService port=${backendPort}`);

apps/server/integration/OrchestrationEngineHarness.integration.ts

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ import {
2323
} from "effect";
2424

2525
import { CheckpointStoreLive } from "../src/checkpointing/Layers/CheckpointStore.ts";
26-
import { CheckpointStore } from "../src/checkpointing/Services/CheckpointStore.ts";
26+
import {
27+
CheckpointStore,
28+
type CheckpointStoreShape,
29+
} from "../src/checkpointing/Services/CheckpointStore.ts";
2730
import { GitCoreLive } from "../src/git/Layers/GitCore.ts";
2831
import { GitCore, type GitCoreShape } from "../src/git/Services/GitCore.ts";
2932
import { TextGeneration, type TextGenerationShape } from "../src/git/Services/TextGeneration.ts";
@@ -33,15 +36,24 @@ import { ProjectionCheckpointRepositoryLive } from "../src/persistence/Layers/Pr
3336
import { ProjectionPendingApprovalRepositoryLive } from "../src/persistence/Layers/ProjectionPendingApprovals.ts";
3437
import { ProviderSessionRuntimeRepositoryLive } from "../src/persistence/Layers/ProviderSessionRuntime.ts";
3538
import { makeSqlitePersistenceLive } from "../src/persistence/Layers/Sqlite.ts";
36-
import { ProjectionCheckpointRepository } from "../src/persistence/Services/ProjectionCheckpoints.ts";
37-
import { ProjectionPendingApprovalRepository } from "../src/persistence/Services/ProjectionPendingApprovals.ts";
39+
import {
40+
ProjectionCheckpointRepository,
41+
type ProjectionCheckpointRepositoryShape,
42+
} from "../src/persistence/Services/ProjectionCheckpoints.ts";
43+
import {
44+
ProjectionPendingApprovalRepository,
45+
type ProjectionPendingApprovalRepositoryShape,
46+
} from "../src/persistence/Services/ProjectionPendingApprovals.ts";
3847
import { ProviderUnsupportedError } from "../src/provider/Errors.ts";
3948
import { ProviderAdapterRegistry } from "../src/provider/Services/ProviderAdapterRegistry.ts";
4049
import { ProviderSessionDirectoryLive } from "../src/provider/Layers/ProviderSessionDirectory.ts";
4150
import { makeProviderServiceLive } from "../src/provider/Layers/ProviderService.ts";
4251
import { makeCodexAdapterLive } from "../src/provider/Layers/CodexAdapter.ts";
4352
import { CodexAdapter } from "../src/provider/Services/CodexAdapter.ts";
44-
import { ProviderService } from "../src/provider/Services/ProviderService.ts";
53+
import {
54+
ProviderService,
55+
type ProviderServiceShape,
56+
} from "../src/provider/Services/ProviderService.ts";
4557
import { AnalyticsService } from "../src/telemetry/Services/AnalyticsService.ts";
4658
import { CheckpointReactorLive } from "../src/orchestration/Layers/CheckpointReactor.ts";
4759
import { OrchestrationEngineLive } from "../src/orchestration/Layers/OrchestrationEngine.ts";
@@ -55,11 +67,18 @@ import {
5567
OrchestrationEngineService,
5668
type OrchestrationEngineShape,
5769
} from "../src/orchestration/Services/OrchestrationEngine.ts";
58-
import { OrchestrationReactor } from "../src/orchestration/Services/OrchestrationReactor.ts";
59-
import { ProjectionSnapshotQuery } from "../src/orchestration/Services/ProjectionSnapshotQuery.ts";
70+
import {
71+
OrchestrationReactor,
72+
type OrchestrationReactorShape,
73+
} from "../src/orchestration/Services/OrchestrationReactor.ts";
74+
import {
75+
ProjectionSnapshotQuery,
76+
type ProjectionSnapshotQueryShape,
77+
} from "../src/orchestration/Services/ProjectionSnapshotQuery.ts";
6078
import {
6179
RuntimeReceiptBus,
6280
type OrchestrationRuntimeReceipt,
81+
type RuntimeReceiptBusShape,
6382
} from "../src/orchestration/Services/RuntimeReceiptBus.ts";
6483

6584
import {
@@ -156,7 +175,7 @@ const tryRuntimePromise = <A>(operation: string, run: () => Promise<A>) =>
156175
Effect.tryPromise({
157176
try: run,
158177
catch: (cause) => new OrchestrationHarnessRuntimeError({ operation, cause }),
159-
});
178+
}) as Effect.Effect<A, OrchestrationHarnessRuntimeError>;
160179

161180
function makeFailingPartialService<Service extends object>(
162181
name: string,
@@ -342,32 +361,60 @@ export const makeOrchestrationIntegrationHarness = (
342361
Layer.provideMerge(NodeServices.layer),
343362
);
344363

345-
const runtime = ManagedRuntime.make(layer);
364+
const runtime = ManagedRuntime.make(
365+
layer as unknown as Layer.Layer<never, OrchestrationHarnessRuntimeError, never>,
366+
);
346367
const engine = yield* tryRuntimePromise("load OrchestrationEngine service", () =>
347-
runtime.runPromise(Effect.service(OrchestrationEngineService)),
368+
runtime.runPromise(
369+
Effect.service(
370+
OrchestrationEngineService,
371+
) as unknown as Effect.Effect<OrchestrationEngineShape>,
372+
),
348373
).pipe(Effect.orDie);
349374
const reactor = yield* tryRuntimePromise("load OrchestrationReactor service", () =>
350-
runtime.runPromise(Effect.service(OrchestrationReactor)),
375+
runtime.runPromise(
376+
Effect.service(OrchestrationReactor) as unknown as Effect.Effect<OrchestrationReactorShape>,
377+
),
351378
).pipe(Effect.orDie);
352379
const snapshotQuery = yield* tryRuntimePromise("load ProjectionSnapshotQuery service", () =>
353-
runtime.runPromise(Effect.service(ProjectionSnapshotQuery)),
380+
runtime.runPromise(
381+
Effect.service(
382+
ProjectionSnapshotQuery,
383+
) as unknown as Effect.Effect<ProjectionSnapshotQueryShape>,
384+
),
354385
).pipe(Effect.orDie);
355386
const providerService = yield* tryRuntimePromise("load ProviderService service", () =>
356-
runtime.runPromise(Effect.service(ProviderService)),
387+
runtime.runPromise(
388+
Effect.service(ProviderService) as unknown as Effect.Effect<ProviderServiceShape>,
389+
),
357390
).pipe(Effect.orDie);
358391
const checkpointStore = yield* tryRuntimePromise("load CheckpointStore service", () =>
359-
runtime.runPromise(Effect.service(CheckpointStore)),
392+
runtime.runPromise(
393+
Effect.service(CheckpointStore) as unknown as Effect.Effect<CheckpointStoreShape>,
394+
),
360395
).pipe(Effect.orDie);
361396
const checkpointRepository = yield* tryRuntimePromise(
362397
"load ProjectionCheckpointRepository service",
363-
() => runtime.runPromise(Effect.service(ProjectionCheckpointRepository)),
398+
() =>
399+
runtime.runPromise(
400+
Effect.service(
401+
ProjectionCheckpointRepository,
402+
) as unknown as Effect.Effect<ProjectionCheckpointRepositoryShape>,
403+
),
364404
).pipe(Effect.orDie);
365405
const pendingApprovalRepository = yield* tryRuntimePromise(
366406
"load ProjectionPendingApprovalRepository service",
367-
() => runtime.runPromise(Effect.service(ProjectionPendingApprovalRepository)),
407+
() =>
408+
runtime.runPromise(
409+
Effect.service(
410+
ProjectionPendingApprovalRepository,
411+
) as unknown as Effect.Effect<ProjectionPendingApprovalRepositoryShape>,
412+
),
368413
).pipe(Effect.orDie);
369414
const runtimeReceiptBus = yield* tryRuntimePromise("load RuntimeReceiptBus service", () =>
370-
runtime.runPromise(Effect.service(RuntimeReceiptBus)),
415+
runtime.runPromise(
416+
Effect.service(RuntimeReceiptBus) as unknown as Effect.Effect<RuntimeReceiptBusShape>,
417+
),
371418
).pipe(Effect.orDie);
372419

373420
const scope = yield* Scope.make("sequential");
@@ -418,7 +465,7 @@ export const makeOrchestrationIntegrationHarness = (
418465
) =>
419466
waitFor(
420467
pendingApprovalRepository
421-
.getByRequestId({ requestId: ApprovalRequestId.makeUnsafe(requestId) })
468+
.getByRequestId({ requestId: ApprovalRequestId.make(requestId) })
422469
.pipe(
423470
Effect.map((row) =>
424471
Option.match(row, {

apps/server/integration/TestProviderAdapter.integration.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function missingSessionEffect(
226226
export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapterHarnessOptions) =>
227227
Effect.gen(function* () {
228228
const provider = options?.provider ?? "codex";
229-
const runtimeProvider = ProviderDriverKind.makeUnsafe(provider);
229+
const runtimeProvider = ProviderDriverKind.make(provider);
230230
const runtimeEvents = yield* Queue.unbounded<ProviderRuntimeEvent>();
231231
let sessionCount = 0;
232232
const sessions = new Map<ThreadId, SessionState>();
@@ -291,7 +291,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter
291291

292292
state.turnCount += 1;
293293
const turnCount = state.turnCount;
294-
const turnId = TurnId.makeUnsafe(`turn-${turnCount}`);
294+
const turnId = TurnId.make(`turn-${turnCount}`);
295295

296296
const response = state.queuedResponses.shift();
297297
if (!response) {
@@ -309,7 +309,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter
309309
...(fixtureEvent as Record<string, unknown>),
310310
eventId: randomUUID(),
311311
provider,
312-
sessionId: RuntimeSessionId.makeUnsafe(String(input.threadId)),
312+
sessionId: RuntimeSessionId.make(String(input.threadId)),
313313
createdAt: nowIso(),
314314
};
315315
rawEvent.threadId = state.snapshot.threadId;
@@ -365,7 +365,7 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter
365365
if (deferredTurnCompletedEvents.length === 0) {
366366
yield* emit({
367367
type: "turn.completed",
368-
eventId: EventId.makeUnsafe(randomUUID()),
368+
eventId: EventId.make(randomUUID()),
369369
provider: runtimeProvider,
370370
createdAt: nowIso(),
371371
threadId: state.snapshot.threadId,

apps/server/integration/fixtures/providerRuntime.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ const PROVIDER = "codex" as const;
55
const SESSION_ID = "fixture-session";
66
const THREAD_ID = "fixture-thread";
77
const TURN_ID = "fixture-turn";
8-
const REQUEST_ID = RuntimeRequestId.makeUnsafe("req-1");
8+
const REQUEST_ID = RuntimeRequestId.make("req-1");
99

1010
function baseEvent(
1111
eventId: string,
1212
createdAt: string,
1313
): Pick<LegacyProviderRuntimeEvent, "eventId" | "provider" | "sessionId" | "createdAt"> {
1414
return {
15-
eventId: EventId.makeUnsafe(eventId),
15+
eventId: EventId.make(eventId),
1616
provider: PROVIDER,
1717
sessionId: SESSION_ID,
1818
createdAt,

apps/server/integration/orchestrationEngine.integration.test.ts

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
ThreadId,
1414
} from "@t3tools/contracts";
1515
import { assert, it } from "@effect/vitest";
16-
import { Effect, Option, Schema } from "effect";
16+
import { Effect, Option, Schema, Scope } from "effect";
1717

1818
import type { TestTurnResponse } from "./TestProviderAdapter.integration.ts";
1919
import {
@@ -29,14 +29,13 @@ import type {
2929
} from "../src/orchestration/Services/RuntimeReceiptBus.ts";
3030
import * as NodeServices from "@effect/platform-node/NodeServices";
3131

32-
const asMessageId = (value: string): MessageId => MessageId.makeUnsafe(value);
33-
const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value);
34-
const asEventId = (value: string): EventId => EventId.makeUnsafe(value);
35-
const asApprovalRequestId = (value: string): ApprovalRequestId =>
36-
ApprovalRequestId.makeUnsafe(value);
32+
const asMessageId = (value: string): MessageId => MessageId.make(value);
33+
const asProjectId = (value: string): ProjectId => ProjectId.make(value);
34+
const asEventId = (value: string): EventId => EventId.make(value);
35+
const asApprovalRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.make(value);
3736

3837
const PROJECT_ID = asProjectId("project-1");
39-
const THREAD_ID = ThreadId.makeUnsafe("thread-1");
38+
const THREAD_ID = ThreadId.make("thread-1");
4039
const FIXTURE_TURN_ID = "fixture-turn";
4140
const APPROVAL_REQUEST_ID = asApprovalRequestId("req-approval-1");
4241
type IntegrationProvider = ProviderKind;
@@ -90,7 +89,7 @@ function withHarness<A, E>(
9089
makeOrchestrationIntegrationHarness({ provider }),
9190
use,
9291
(harness) => harness.dispose,
93-
).pipe(Effect.provide(NodeServices.layer));
92+
).pipe(Effect.provide(NodeServices.layer)) as Effect.Effect<A, E, Scope.Scope>;
9493
}
9594

9695
function withRealCodexHarness<A, E>(
@@ -111,7 +110,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) =>
111110

112111
yield* harness.engine.dispatch({
113112
type: "project.create",
114-
commandId: CommandId.makeUnsafe("cmd-project-create"),
113+
commandId: CommandId.make("cmd-project-create"),
115114
projectId: PROJECT_ID,
116115
title: "Integration Project",
117116
workspaceRoot: harness.workspaceDir,
@@ -121,7 +120,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) =>
121120

122121
yield* harness.engine.dispatch({
123122
type: "thread.create",
124-
commandId: CommandId.makeUnsafe("cmd-thread-create"),
123+
commandId: CommandId.make("cmd-thread-create"),
125124
threadId: THREAD_ID,
126125
projectId: PROJECT_ID,
127126
title: "Integration Thread",
@@ -143,7 +142,7 @@ const startTurn = (input: {
143142
}) =>
144143
input.harness.engine.dispatch({
145144
type: "thread.turn.start",
146-
commandId: CommandId.makeUnsafe(input.commandId),
145+
commandId: CommandId.make(input.commandId),
147146
threadId: THREAD_ID,
148147
message: {
149148
messageId: asMessageId(input.messageId),
@@ -250,7 +249,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)(
250249

251250
yield* harness.engine.dispatch({
252251
type: "project.create",
253-
commandId: CommandId.makeUnsafe("cmd-project-create-real-codex"),
252+
commandId: CommandId.make("cmd-project-create-real-codex"),
254253
projectId: PROJECT_ID,
255254
title: "Integration Project",
256255
workspaceRoot: harness.workspaceDir,
@@ -260,7 +259,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)(
260259

261260
yield* harness.engine.dispatch({
262261
type: "thread.create",
263-
commandId: CommandId.makeUnsafe("cmd-thread-create-real-codex"),
262+
commandId: CommandId.make("cmd-thread-create-real-codex"),
264263
threadId: THREAD_ID,
265264
projectId: PROJECT_ID,
266265
title: "Integration Thread",
@@ -274,7 +273,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)(
274273

275274
yield* harness.engine.dispatch({
276275
type: "thread.turn.start",
277-
commandId: CommandId.makeUnsafe("cmd-turn-start-real-codex-1"),
276+
commandId: CommandId.make("cmd-turn-start-real-codex-1"),
278277
threadId: THREAD_ID,
279278
message: {
280279
messageId: asMessageId("msg-real-codex-1"),
@@ -301,7 +300,7 @@ it.live.skipIf(!process.env.CODEX_BINARY_PATH)(
301300

302301
yield* harness.engine.dispatch({
303302
type: "thread.turn.start",
304-
commandId: CommandId.makeUnsafe("cmd-turn-start-real-codex-2"),
303+
commandId: CommandId.make("cmd-turn-start-real-codex-2"),
305304
threadId: THREAD_ID,
306305
message: {
307306
messageId: asMessageId("msg-real-codex-2"),
@@ -566,7 +565,7 @@ it.live("tracks approval requests and resolves pending approvals on user respons
566565

567566
yield* harness.engine.dispatch({
568567
type: "thread.approval.respond",
569-
commandId: CommandId.makeUnsafe("cmd-approval-respond"),
568+
commandId: CommandId.make("cmd-approval-respond"),
570569
threadId: THREAD_ID,
571570
requestId: APPROVAL_REQUEST_ID,
572571
decision: "accept",
@@ -798,7 +797,7 @@ it.live("reverts to an earlier checkpoint and trims checkpoint projections + git
798797

799798
yield* harness.engine.dispatch({
800799
type: "thread.checkpoint.revert",
801-
commandId: CommandId.makeUnsafe("cmd-checkpoint-revert"),
800+
commandId: CommandId.make("cmd-checkpoint-revert"),
802801
threadId: THREAD_ID,
803802
turnCount: 1,
804803
createdAt: nowIso(),
@@ -858,7 +857,7 @@ it.live(
858857

859858
yield* harness.engine.dispatch({
860859
type: "thread.checkpoint.revert",
861-
commandId: CommandId.makeUnsafe("cmd-checkpoint-revert-no-session"),
860+
commandId: CommandId.make("cmd-checkpoint-revert-no-session"),
862861
threadId: THREAD_ID,
863862
turnCount: 0,
864863
createdAt: nowIso(),
@@ -1093,7 +1092,7 @@ it.live("forwards claudeAgent approval responses to the provider session", () =>
10931092

10941093
yield* harness.engine.dispatch({
10951094
type: "thread.approval.respond",
1096-
commandId: CommandId.makeUnsafe("cmd-claude-approval-respond"),
1095+
commandId: CommandId.make("cmd-claude-approval-respond"),
10971096
threadId: THREAD_ID,
10981097
requestId: APPROVAL_REQUEST_ID,
10991098
decision: "accept",
@@ -1163,7 +1162,7 @@ it.live("forwards thread.turn.interrupt to claudeAgent provider sessions", () =>
11631162

11641163
yield* harness.engine.dispatch({
11651164
type: "thread.turn.interrupt",
1166-
commandId: CommandId.makeUnsafe("cmd-turn-interrupt-claude"),
1165+
commandId: CommandId.make("cmd-turn-interrupt-claude"),
11671166
threadId: THREAD_ID,
11681167
createdAt: nowIso(),
11691168
});
@@ -1277,7 +1276,7 @@ it.live("reverts claudeAgent turns and rolls back provider conversation state",
12771276

12781277
yield* harness.engine.dispatch({
12791278
type: "thread.checkpoint.revert",
1280-
commandId: CommandId.makeUnsafe("cmd-checkpoint-revert-claude"),
1279+
commandId: CommandId.make("cmd-checkpoint-revert-claude"),
12811280
threadId: THREAD_ID,
12821281
turnCount: 1,
12831282
createdAt: nowIso(),

0 commit comments

Comments
 (0)