- Introduce a dedicated `GitVcsDriver` service and `vcsLayer` - Update server, orchestration, and workspace wiring to use the new layer - Adjust tests and mocks for the new git-specific dependency
Unified · Split
| @@ -33,7 +33,6 @@ import { ProjectionCheckpointRepositoryLive } from "../src/persistence/Layers/Pr · 32 unmodified lines | ||
| 33 | 33 | import { ProjectionPendingApprovalRepositoryLive } from "../src/persistence/Layers/ProjectionPendingApprovals.ts"; |
| 34 | 34 | import { ProviderSessionRuntimeRepositoryLive } from "../src/persistence/Layers/ProviderSessionRuntime.ts"; |
| 35 | 35 | import { makeSqlitePersistenceLive } from "../src/persistence/Layers/Sqlite.ts"; |
| 36 | −import { VcsDriver, type VcsDriverShape } from "../src/vcs/VcsDriver.ts"; | |
| 37 | 36 | import { ProjectionCheckpointRepository } from "../src/persistence/Services/ProjectionCheckpoints.ts"; |
| 38 | 37 | import { ProjectionPendingApprovalRepository } from "../src/persistence/Services/ProjectionPendingApprovals.ts"; |
| 39 | 38 | import { makeAdapterRegistryMock } from "../src/provider/testUtils/providerAdapterRegistryMock.ts"; |
| @@ -292,7 +291,7 @@ export const makeOrchestrationIntegrationHarness = ( · 252 unmodified lines | ||
| 292 | 291 | Layer.provide(providerEventLoggersLayer), |
| 293 | 292 | ); |
| 294 | 293 | |
| 295 | − const checkpointStoreLayer = CheckpointStoreLive.pipe(Layer.provide(GitVcsDriver.layer)); | |
| 294 | + const checkpointStoreLayer = CheckpointStoreLive.pipe(Layer.provide(GitVcsDriver.vcsLayer)); | |
| 296 | 295 | const projectionSnapshotQueryLayer = OrchestrationProjectionSnapshotQueryLive; |
| 297 | 296 | const runtimeServicesLayer = Layer.mergeAll( |
| 298 | 297 | projectionSnapshotQueryLayer, |
| @@ -308,17 +307,17 @@ export const makeOrchestrationIntegrationHarness = ( · 9 unmodified lines | ||
| 308 | 307 | Layer.provideMerge(runtimeServicesLayer), |
| 309 | 308 | Layer.provideMerge(serverSettingsLayer), |
| 310 | 309 | ); |
| 311 | − const vcsDriverLayer = Layer.succeed(VcsDriver, { | |
| 312 | − renameBranch: (input: Parameters<VcsDriverShape["renameBranch"]>[0]) => | |
| 310 | + const gitVcsDriverLayer = Layer.succeed(GitVcsDriver.GitVcsDriver, { | |
| 311 | + renameBranch: (input: Parameters<GitVcsDriver.GitVcsDriverShape["renameBranch"]>[0]) => | |
| 313 | 312 | Effect.succeed({ branch: input.newBranch }), |
| 314 | − } as unknown as VcsDriverShape); | |
| 313 | + } as unknown as GitVcsDriver.GitVcsDriverShape); | |
| 315 | 314 | const textGenerationLayer = Layer.succeed(TextGeneration, { |
| 316 | 315 | generateBranchName: () => Effect.succeed({ branch: "update" }), |
| 317 | 316 | generateThreadTitle: () => Effect.succeed({ title: "New thread" }), |
| 318 | 317 | } as unknown as TextGenerationShape); |
| 319 | 318 | const providerCommandReactorLayer = ProviderCommandReactorLive.pipe( |
| 320 | 319 | Layer.provideMerge(runtimeServicesLayer), |
| 321 | − Layer.provideMerge(vcsDriverLayer), | |
| 320 | + Layer.provideMerge(gitVcsDriverLayer), | |
| 322 | 321 | Layer.provideMerge(textGenerationLayer), |
| 323 | 322 | Layer.provideMerge(serverSettingsLayer), |
| 324 | 323 | ); |
| @@ -343,7 +342,7 @@ export const makeOrchestrationIntegrationHarness = ( · 18 unmodified lines | ||
| 343 | 342 | Layer.provideMerge( |
| 344 | 343 | WorkspaceEntriesLive.pipe( |
| 345 | 344 | Layer.provide(WorkspacePathsLive), |
| 346 | − Layer.provideMerge(GitVcsDriver.layer), | |
| 345 | + Layer.provideMerge(GitVcsDriver.vcsLayer), | |
| 347 | 346 | Layer.provide(NodeServices.layer), |
| 348 | 347 | ), |
| 349 | 348 | ), |
| @@ -18,7 +18,7 @@ const ServerConfigLayer = ServerConfig.layerTest(process.cwd(), { · 17 unmodified lines | ||
| 18 | 18 | prefix: "t3-checkpoint-store-test-", |
| 19 | 19 | }); |
| 20 | 20 | const VcsProcessTestLayer = VcsProcess.layer.pipe(Layer.provide(NodeServices.layer)); |
| 21 | −const VcsDriverTestLayer = GitVcsDriver.layer.pipe(Layer.provide(VcsProcessTestLayer)); | |
| 21 | +const VcsDriverTestLayer = GitVcsDriver.vcsLayer.pipe(Layer.provide(VcsProcessTestLayer)); | |
| 22 | 22 | const CheckpointStoreTestLayer = CheckpointStoreLive.pipe( |
| 23 | 23 | Layer.provideMerge(VcsDriverTestLayer), |
| 24 | 24 | Layer.provideMerge(NodeServices.layer), |
| @@ -23,7 +23,6 @@ import { · 22 unmodified lines | ||
| 23 | 23 | import { type TextGenerationShape, TextGeneration } from "../Services/TextGeneration.ts"; |
| 24 | 24 | import * as GitVcsDriver from "../../vcs/GitVcsDriver.ts"; |
| 25 | 25 | import * as VcsProcess from "../../vcs/VcsProcess.ts"; |
| 26 | −import { VcsDriver } from "../../vcs/VcsDriver.ts"; | |
| 27 | 26 | import { makeGitManager } from "./GitManager.ts"; |
| 28 | 27 | import { ServerConfig } from "../../config.ts"; |
| 29 | 28 | import { ServerSettingsService } from "../../serverSettings.ts"; |
| @@ -212,30 +211,18 @@ function runGit( · 182 unmodified lines | ||
| 212 | 211 | ): Effect.Effect< |
| 213 | 212 | { readonly code: number; readonly stdout: string; readonly stderr: string }, |
| 214 | 213 | GitCommandError, |
| 215 | − VcsDriver | |
| 214 | + GitVcsDriver.GitVcsDriver | |
| 216 | 215 | > { |
| 217 | 216 | return Effect.gen(function* () { |
| 218 | − const vcs = yield* VcsDriver; | |
| 219 | − const result = yield* vcs | |
| 220 | − .execute({ | |
| 221 | − operation: "GitManager.test.runGit", | |
| 222 | − cwd, | |
| 223 | − args, | |
| 224 | − allowNonZeroExit, | |
| 225 | − }) | |
| 226 | − .pipe( | |
| 227 | − Effect.mapError( | |
| 228 | − (error) => | |
| 229 | − new GitCommandError({ | |
| 230 | − operation: "GitManager.test.runGit", | |
| 231 | − command: `git ${args.join(" ")}`, | |
| 232 | − cwd, | |
| 233 | − detail: error.message, | |
| 234 | − }), | |
| 235 | − ), | |
| 236 | − ); | |
| 217 | + const git = yield* GitVcsDriver.GitVcsDriver; | |
| 218 | + const result = yield* git.execute({ | |
| 219 | + operation: "GitManager.test.runGit", | |
| 220 | + cwd, | |
| 221 | + args, | |
| 222 | + allowNonZeroExit, | |
| 223 | + }); | |
| 237 | 224 | return { |
| 238 | − code: result.exitCode, | |
| 225 | + code: result.code, | |
| 239 | 226 | stdout: result.stdout, |
| 240 | 227 | stderr: result.stderr, |
| 241 | 228 | }; |
| @@ -247,7 +234,7 @@ function initRepo( · 5 unmodified lines | ||
| 247 | 234 | ): Effect.Effect< |
| 248 | 235 | void, |
| 249 | 236 | PlatformError.PlatformError | GitCommandError, |
| 250 | − FileSystem.FileSystem | Scope.Scope | VcsDriver | |
| 237 | + FileSystem.FileSystem | Scope.Scope | GitVcsDriver.GitVcsDriver | |
| 251 | 238 | > { |
| 252 | 239 | return Effect.gen(function* () { |
| 253 | 240 | const fs = yield* FileSystem.FileSystem; |
| @@ -263,7 +250,7 @@ function initRepo( · 9 unmodified lines | ||
| 263 | 250 | function createBareRemote(): Effect.Effect< |
| 264 | 251 | string, |
| 265 | 252 | PlatformError.PlatformError | GitCommandError, |
| 266 | − FileSystem.FileSystem | Scope.Scope | VcsDriver | |
| 253 | + FileSystem.FileSystem | Scope.Scope | GitVcsDriver.GitVcsDriver | |
| 267 | 254 | > { |
| 268 | 255 | return Effect.gen(function* () { |
| 269 | 256 | const remoteDir = yield* makeTempDir("t3code-git-remote-"); |
| @@ -277,7 +264,7 @@ function configureRemote( · 7 unmodified lines | ||
| 277 | 264 | remoteName: string, |
| 278 | 265 | remotePath: string, |
| 279 | 266 | fetchNamespace: string, |
| 280 | −): Effect.Effect<void, GitCommandError, VcsDriver> { | |
| 267 | +): Effect.Effect<void, GitCommandError, GitVcsDriver.GitVcsDriver> { | |
| 281 | 268 | return Effect.gen(function* () { |
| 282 | 269 | yield* runGit(cwd, ["config", `remote.${remoteName}.url`, remotePath]); |
| 283 | 270 | yield* runGit(cwd, [ |
| @@ -49,7 +49,7 @@ import { · 48 unmodified lines | ||
| 49 | 49 | decodeGitHubPullRequestListJson, |
| 50 | 50 | formatGitHubJsonDecodeError, |
| 51 | 51 | } from "../githubPullRequests.ts"; |
| 52 | −import { VcsDriver } from "../../vcs/VcsDriver.ts"; | |
| 52 | +import { GitVcsDriver } from "../../vcs/GitVcsDriver.ts"; | |
| 53 | 53 | |
| 54 | 54 | const COMMIT_TIMEOUT_MS = 10 * 60_000; |
| 55 | 55 | const MAX_PROGRESS_TEXT_LENGTH = 500; |
| @@ -491,7 +491,7 @@ function toPullRequestHeadRemoteInfo(pr: { · 435 unmodified lines | ||
| 491 | 491 | } |
| 492 | 492 | |
| 493 | 493 | export const makeGitManager = Effect.fn("makeGitManager")(function* () { |
| 494 | − const gitCore = yield* VcsDriver; | |
| 494 | + const gitCore = yield* GitVcsDriver; | |
| 495 | 495 | const gitHubCli = yield* GitHubCli; |
| 496 | 496 | const textGeneration = yield* TextGeneration; |
| 497 | 497 | const projectSetupScriptRunner = yield* ProjectSetupScriptRunner; |
| @@ -307,11 +307,11 @@ describe("CheckpointReactor", () => { · 306 unmodified lines | ||
| 307 | 307 | Layer.provideMerge(RuntimeReceiptBusLive), |
| 308 | 308 | Layer.provideMerge(Layer.succeed(ProviderService, provider.service)), |
| 309 | 309 | Layer.provideMerge(gitStatusBroadcasterLayer), |
| 310 | − Layer.provideMerge(CheckpointStoreLive.pipe(Layer.provide(GitVcsDriver.layer))), | |
| 310 | + Layer.provideMerge(CheckpointStoreLive.pipe(Layer.provide(GitVcsDriver.vcsLayer))), | |
| 311 | 311 | Layer.provideMerge( |
| 312 | 312 | WorkspaceEntriesLive.pipe( |
| 313 | 313 | Layer.provide(WorkspacePathsLive), |
| 314 | − Layer.provideMerge(GitVcsDriver.layer), | |
| 314 | + Layer.provideMerge(GitVcsDriver.vcsLayer), | |
| 315 | 315 | ), |
| 316 | 316 | ), |
| 317 | 317 | Layer.provideMerge(WorkspacePathsLive), |
| @@ -51,7 +51,7 @@ import { OrchestrationEngineService } from "../Services/OrchestrationEngine.ts"; · 50 unmodified lines | ||
| 51 | 51 | import { ProviderCommandReactor } from "../Services/ProviderCommandReactor.ts"; |
| 52 | 52 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 53 | 53 | import { ServerSettingsService } from "../../serverSettings.ts"; |
| 54 | −import { VcsDriver, type VcsDriverShape } from "../../vcs/VcsDriver.ts"; | |
| 54 | +import * as GitVcsDriver from "../../vcs/GitVcsDriver.ts"; | |
| 55 | 55 | |
| 56 | 56 | const asProjectId = (value: string): ProjectId => ProjectId.make(value); |
| 57 | 57 | const asApprovalRequestId = (value: string): ApprovalRequestId => ApprovalRequestId.make(value); |
| @@ -324,7 +324,11 @@ describe("ProviderCommandReactor", () => { · 266 unmodified lines | ||
| 324 | 324 | const layer = ProviderCommandReactorLive.pipe( |
| 325 | 325 | Layer.provideMerge(orchestrationLayer), |
| 326 | 326 | Layer.provideMerge(Layer.succeed(ProviderService, service)), |
| 327 | − Layer.provideMerge(Layer.succeed(VcsDriver, { renameBranch } as unknown as VcsDriverShape)), | |
| 327 | + Layer.provideMerge( | |
| 328 | + Layer.succeed(GitVcsDriver.GitVcsDriver, { | |
| 329 | + renameBranch, | |
| 330 | + } as unknown as GitVcsDriver.GitVcsDriverShape), | |
| 331 | + ), | |
| 328 | 332 | Layer.provideMerge( |
| 329 | 333 | Layer.succeed(GitStatusBroadcaster, { |
| 330 | 334 | getStatus: () => Effect.die("getStatus should not be called in this test"), |
| @@ -28,7 +28,7 @@ import { · 27 unmodified lines | ||
| 28 | 28 | type ProviderCommandReactorShape, |
| 29 | 29 | } from "../Services/ProviderCommandReactor.ts"; |
| 30 | 30 | import { ServerSettingsService } from "../../serverSettings.ts"; |
| 31 | −import { VcsDriver } from "../../vcs/VcsDriver.ts"; | |
| 31 | +import { GitVcsDriver } from "../../vcs/GitVcsDriver.ts"; | |
| 32 | 32 | |
| 33 | 33 | type ProviderIntentEvent = Extract< |
| 34 | 34 | OrchestrationEvent, |
| @@ -168,7 +168,7 @@ function buildGeneratedWorktreeBranchName(raw: string): string { · 133 unmodified lines | ||
| 168 | 168 | const make = Effect.gen(function* () { |
| 169 | 169 | const orchestrationEngine = yield* OrchestrationEngineService; |
| 170 | 170 | const providerService = yield* ProviderService; |
| 171 | − const git = yield* VcsDriver; | |
| 171 | + const git = yield* GitVcsDriver; | |
| 172 | 172 | const gitStatusBroadcaster = yield* GitStatusBroadcaster; |
| 173 | 173 | const textGeneration = yield* TextGeneration; |
| 174 | 174 | const serverSettingsService = yield* ServerSettingsService; |
| @@ -104,6 +104,7 @@ import { · 103 unmodified lines | ||
| 104 | 104 | import { WorkspaceEntriesLive } from "./workspace/Layers/WorkspaceEntries.ts"; |
| 105 | 105 | import { WorkspaceFileSystemLive } from "./workspace/Layers/WorkspaceFileSystem.ts"; |
| 106 | 106 | import { WorkspacePathsLive } from "./workspace/Layers/WorkspacePaths.ts"; |
| 107 | +import * as GitVcsDriver from "./vcs/GitVcsDriver.ts"; | |
| 107 | 108 | import { VcsDriver, type VcsDriverShape } from "./vcs/VcsDriver.ts"; |
| 108 | 109 | import { ServerSecretStoreLive } from "./auth/Layers/ServerSecretStore.ts"; |
| 109 | 110 | import { ServerAuthLive } from "./auth/Layers/ServerAuth.ts"; |
| @@ -315,6 +316,7 @@ const buildAppUnderTest = (options?: { · 205 unmodified lines | ||
| 315 | 316 | serverSettings?: Partial<ServerSettingsShape>; |
| 316 | 317 | open?: Partial<OpenShape>; |
| 317 | 318 | vcsDriver?: Partial<VcsDriverShape>; |
| 319 | + gitVcsDriver?: Partial<GitVcsDriver.GitVcsDriverShape>; | |
| 318 | 320 | gitManager?: Partial<GitManagerShape>; |
| 319 | 321 | gitStatusBroadcaster?: Partial<GitStatusBroadcasterShape>; |
| 320 | 322 | projectSetupScriptRunner?: Partial<ProjectSetupScriptRunnerShape>; |
| @@ -384,6 +386,9 @@ const buildAppUnderTest = (options?: { · 63 unmodified lines | ||
| 384 | 386 | filterIgnoredPaths: (_cwd, relativePaths) => Effect.succeed(relativePaths), |
| 385 | 387 | ...options?.layers?.vcsDriver, |
| 386 | 388 | }); |
| 389 | + const gitVcsDriverLayer = Layer.mock(GitVcsDriver.GitVcsDriver)({ | |
| 390 | + ...options?.layers?.gitVcsDriver, | |
| 391 | + }); | |
| 387 | 392 | const gitManagerLayer = Layer.mock(GitManager)({ |
| 388 | 393 | ...options?.layers?.gitManager, |
| 389 | 394 | }); |
| @@ -444,6 +449,7 @@ const buildAppUnderTest = (options?: { · 54 unmodified lines | ||
| 444 | 449 | }), |
| 445 | 450 | ), |
| 446 | 451 | Layer.provide(gitManagerLayer), |
| 452 | + Layer.provide(gitVcsDriverLayer), | |
| 447 | 453 | Layer.provideMerge(gitStatusBroadcasterLayer), |
| 448 | 454 | Layer.provide( |
| 449 | 455 | Layer.mock(ProjectSetupScriptRunner)({ |
| @@ -2377,7 +2383,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 1927 unmodified lines | ||
| 2377 | 2383 | worktreePath: null, |
| 2378 | 2384 | }), |
| 2379 | 2385 | }, |
| 2380 | − vcsDriver: { | |
| 2386 | + gitVcsDriver: { | |
| 2381 | 2387 | pullCurrentBranch: () => |
| 2382 | 2388 | Effect.succeed({ |
| 2383 | 2389 | status: "pulled", |
| @@ -2531,7 +2537,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 147 unmodified lines | ||
| 2531 | 2537 | let statusCalls = 0; |
| 2532 | 2538 | yield* buildAppUnderTest({ |
| 2533 | 2539 | layers: { |
| 2534 | − vcsDriver: { | |
| 2540 | + gitVcsDriver: { | |
| 2535 | 2541 | pullCurrentBranch: () => Effect.fail(gitError), |
| 2536 | 2542 | }, |
| 2537 | 2543 | gitManager: { |
| @@ -2685,7 +2691,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 147 unmodified lines | ||
| 2685 | 2691 | Effect.gen(function* () { |
| 2686 | 2692 | yield* buildAppUnderTest({ |
| 2687 | 2693 | layers: { |
| 2688 | − vcsDriver: { | |
| 2694 | + gitVcsDriver: { | |
| 2689 | 2695 | pullCurrentBranch: () => |
| 2690 | 2696 | Effect.succeed({ |
| 2691 | 2697 | status: "pulled" as const, |
| @@ -3499,13 +3505,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 807 unmodified lines | ||
| 3499 | 3505 | pr: null, |
| 3500 | 3506 | }), |
| 3501 | 3507 | ); |
| 3502 | − const createWorktree = vi.fn((_: Parameters<VcsDriverShape["createWorktree"]>[0]) => | |
| 3503 | − Effect.succeed({ | |
| 3504 | − worktree: { | |
| 3505 | − branch: "t3code/bootstrap-branch", | |
| 3506 | − path: "/tmp/bootstrap-worktree", | |
| 3507 | − }, | |
| 3508 | − }), | |
| 3508 | + const createWorktree = vi.fn( | |
| 3509 | + (_: Parameters<GitVcsDriver.GitVcsDriverShape["createWorktree"]>[0]) => | |
| 3510 | + Effect.succeed({ | |
| 3511 | + worktree: { | |
| 3512 | + branch: "t3code/bootstrap-branch", | |
| 3513 | + path: "/tmp/bootstrap-worktree", | |
| 3514 | + }, | |
| 3515 | + }), | |
| 3509 | 3516 | ); |
| 3510 | 3517 | const runForThread = vi.fn( |
| 3511 | 3518 | (_: Parameters<ProjectSetupScriptRunnerShape["runForThread"]>[0]) => |
| @@ -3520,7 +3527,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 8 unmodified lines | ||
| 3520 | 3527 | |
| 3521 | 3528 | yield* buildAppUnderTest({ |
| 3522 | 3529 | layers: { |
| 3523 | − vcsDriver: { | |
| 3530 | + gitVcsDriver: { | |
| 3524 | 3531 | createWorktree, |
| 3525 | 3532 | }, |
| 3526 | 3533 | gitStatusBroadcaster: { |
| @@ -3624,13 +3631,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 97 unmodified lines | ||
| 3624 | 3631 | it.effect("records setup-script failures without aborting bootstrap turn start", () => |
| 3625 | 3632 | Effect.gen(function* () { |
| 3626 | 3633 | const dispatchedCommands: Array<OrchestrationCommand> = []; |
| 3627 | − const createWorktree = vi.fn((_: Parameters<VcsDriverShape["createWorktree"]>[0]) => | |
| 3628 | − Effect.succeed({ | |
| 3629 | − worktree: { | |
| 3630 | − branch: "t3code/bootstrap-branch", | |
| 3631 | − path: "/tmp/bootstrap-worktree", | |
| 3632 | − }, | |
| 3633 | − }), | |
| 3634 | + const createWorktree = vi.fn( | |
| 3635 | + (_: Parameters<GitVcsDriver.GitVcsDriverShape["createWorktree"]>[0]) => | |
| 3636 | + Effect.succeed({ | |
| 3637 | + worktree: { | |
| 3638 | + branch: "t3code/bootstrap-branch", | |
| 3639 | + path: "/tmp/bootstrap-worktree", | |
| 3640 | + }, | |
| 3641 | + }), | |
| 3634 | 3642 | ); |
| 3635 | 3643 | const runForThread = vi.fn( |
| 3636 | 3644 | (_: Parameters<ProjectSetupScriptRunnerShape["runForThread"]>[0]) => |
| @@ -3639,7 +3647,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 2 unmodified lines | ||
| 3639 | 3647 | |
| 3640 | 3648 | yield* buildAppUnderTest({ |
| 3641 | 3649 | layers: { |
| 3642 | − vcsDriver: { | |
| 3650 | + gitVcsDriver: { | |
| 3643 | 3651 | createWorktree, |
| 3644 | 3652 | }, |
| 3645 | 3653 | orchestrationEngine: { |
| @@ -3717,13 +3725,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 71 unmodified lines | ||
| 3717 | 3725 | it.effect("does not misattribute setup activity dispatch failures as setup launch failures", () => |
| 3718 | 3726 | Effect.gen(function* () { |
| 3719 | 3727 | const dispatchedCommands: Array<OrchestrationCommand> = []; |
| 3720 | − const createWorktree = vi.fn((_: Parameters<VcsDriverShape["createWorktree"]>[0]) => | |
| 3721 | − Effect.succeed({ | |
| 3722 | − worktree: { | |
| 3723 | − branch: "t3code/bootstrap-branch", | |
| 3724 | − path: "/tmp/bootstrap-worktree", | |
| 3725 | − }, | |
| 3726 | − }), | |
| 3728 | + const createWorktree = vi.fn( | |
| 3729 | + (_: Parameters<GitVcsDriver.GitVcsDriverShape["createWorktree"]>[0]) => | |
| 3730 | + Effect.succeed({ | |
| 3731 | + worktree: { | |
| 3732 | + branch: "t3code/bootstrap-branch", | |
| 3733 | + path: "/tmp/bootstrap-worktree", | |
| 3734 | + }, | |
| 3735 | + }), | |
| 3727 | 3736 | ); |
| 3728 | 3737 | const runForThread = vi.fn( |
| 3729 | 3738 | (_: Parameters<ProjectSetupScriptRunnerShape["runForThread"]>[0]) => |
| @@ -3739,7 +3748,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 9 unmodified lines | ||
| 3739 | 3748 | |
| 3740 | 3749 | yield* buildAppUnderTest({ |
| 3741 | 3750 | layers: { |
| 3742 | − vcsDriver: { | |
| 3751 | + gitVcsDriver: { | |
| 3743 | 3752 | createWorktree, |
| 3744 | 3753 | }, |
| 3745 | 3754 | orchestrationEngine: { |
| @@ -3835,13 +3844,14 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 89 unmodified lines | ||
| 3835 | 3844 | it.effect("cleans up created bootstrap threads when worktree creation defects", () => |
| 3836 | 3845 | Effect.gen(function* () { |
| 3837 | 3846 | const dispatchedCommands: Array<OrchestrationCommand> = []; |
| 3838 | − const createWorktree = vi.fn((_: Parameters<VcsDriverShape["createWorktree"]>[0]) => | |
| 3839 | − Effect.die(new Error("worktree exploded")), | |
| 3847 | + const createWorktree = vi.fn( | |
| 3848 | + (_: Parameters<GitVcsDriver.GitVcsDriverShape["createWorktree"]>[0]) => | |
| 3849 | + Effect.die(new Error("worktree exploded")), | |
| 3840 | 3850 | ); |
| 3841 | 3851 | |
| 3842 | 3852 | yield* buildAppUnderTest({ |
| 3843 | 3853 | layers: { |
| 3844 | − vcsDriver: { | |
| 3854 | + gitVcsDriver: { | |
| 3845 | 3855 | createWorktree, |
| 3846 | 3856 | }, |
| 3847 | 3857 | orchestrationEngine: { |
| @@ -136,7 +136,7 @@ const ReactorLayerLive = Layer.empty.pipe( · 135 unmodified lines | ||
| 136 | 136 | |
| 137 | 137 | const CheckpointingLayerLive = Layer.empty.pipe( |
| 138 | 138 | Layer.provideMerge(CheckpointDiffQueryLive), |
| 139 | − Layer.provideMerge(CheckpointStoreLive.pipe(Layer.provide(GitVcsDriver.layer))), | |
| 139 | + Layer.provideMerge(CheckpointStoreLive.pipe(Layer.provide(GitVcsDriver.vcsLayer))), | |
| 140 | 140 | ); |
| 141 | 141 | |
| 142 | 142 | const ProviderSessionDirectoryLayerLive = ProviderSessionDirectoryLive.pipe( |
| @@ -173,7 +173,7 @@ const TerminalLayerLive = TerminalManagerLive.pipe(Layer.provide(PtyAdapterLive) · 30 unmodified lines | ||
| 173 | 173 | |
| 174 | 174 | const WorkspaceEntriesLayerLive = WorkspaceEntriesLive.pipe( |
| 175 | 175 | Layer.provide(WorkspacePathsLive), |
| 176 | − Layer.provideMerge(GitVcsDriver.layer), | |
| 176 | + Layer.provideMerge(GitVcsDriver.vcsLayer), | |
| 177 | 177 | ); |
| 178 | 178 | |
| 179 | 179 | const WorkspaceFileSystemLayerLive = WorkspaceFileSystemLive.pipe( |
| @@ -18,7 +18,7 @@ const GitVcsDriverTestDependencies = ServerConfig.layerTest(process.cwd(), { · 17 unmodified lines | ||
| 18 | 18 | prefix: "t3-git-vcs-driver-test-", |
| 19 | 19 | }).pipe(Layer.provide(NodeServices.layer)); |
| 20 | 20 | |
| 21 | −it.layer(Layer.empty)("GitVcsDriver.layer", (it) => { | |
| 21 | +it.layer(Layer.empty)("GitVcsDriver.vcsLayer", (it) => { | |
| 22 | 22 | describe("workspace helpers", () => { |
| 23 | 23 | it.effect("filterIgnoredPaths chunks large path lists and preserves kept paths", () => |
| 24 | 24 | Effect.gen(function* () { |
| @@ -32,7 +32,7 @@ it.layer(Layer.empty)("GitVcsDriver.layer", (it) => { · 7 unmodified lines | ||
| 32 | 32 | ); |
| 33 | 33 | |
| 34 | 34 | const seenChunks: string[][] = []; |
| 35 | − const layer = GitVcsDriver.layer.pipe( | |
| 35 | + const layer = GitVcsDriver.vcsLayer.pipe( | |
| 36 | 36 | Layer.provideMerge(GitVcsDriverTestDependencies), |
| 37 | 37 | Layer.provideMerge(NodeServices.layer), |
| 38 | 38 | Layer.provide( |
| @@ -81,7 +81,7 @@ it.layer(Layer.empty)("GitVcsDriver.layer", (it) => { · 42 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | it.effect("listWorkspaceFiles disables fsmonitor and untracked cache helpers", () => |
| 83 | 83 | Effect.gen(function* () { |
| 84 | − const layer = GitVcsDriver.layer.pipe( | |
| 84 | + const layer = GitVcsDriver.vcsLayer.pipe( | |
| 85 | 85 | Layer.provideMerge(GitVcsDriverTestDependencies), |
| 86 | 86 | Layer.provideMerge(NodeServices.layer), |
| 87 | 87 | Layer.provide( |
| @@ -1,10 +1,17 @@ | ||
| 1 | −import { DateTime, Effect, Layer } from "effect"; | |
| 1 | +import { Context, DateTime, Effect, Layer } from "effect"; | |
| 2 | 2 | |
| 3 | 3 | import { VcsProcessExitError } from "@t3tools/contracts"; |
| 4 | 4 | import { makeGitCore } from "../git/Layers/GitCore.ts"; |
| 5 | +import type { GitCoreShape } from "../git/Services/GitCore.ts"; | |
| 5 | 6 | import { VcsDriver, type VcsDriverShape } from "./VcsDriver.ts"; |
| 6 | 7 | import { VcsProcess, type VcsProcessShape } from "./VcsProcess.ts"; |
| 7 | 8 | |
| 9 | +export interface GitVcsDriverShape extends GitCoreShape {} | |
| 10 | + | |
| 11 | +export class GitVcsDriver extends Context.Service<GitVcsDriver, GitVcsDriverShape>()( | |
| 12 | + "t3/vcs/GitVcsDriver", | |
| 13 | +) {} | |
| 14 | + | |
| 8 | 15 | const WORKSPACE_FILES_MAX_OUTPUT_BYTES = 16 * 1024 * 1024; |
| 9 | 16 | const GIT_CHECK_IGNORE_MAX_STDIN_BYTES = 256 * 1024; |
| 10 | 17 | const WORKSPACE_GIT_HARDENED_CONFIG_ARGS = [ |
| @@ -92,9 +99,8 @@ const gitCommand = ( · 81 unmodified lines | ||
| 92 | 99 | : {}), |
| 93 | 100 | }); |
| 94 | 101 | |
| 95 | −export const make = Effect.fn("makeGitVcsDriver")(function* () { | |
| 102 | +export const makeVcsDriver = Effect.fn("makeGitVcsDriver")(function* () { | |
| 96 | 103 | const process = yield* VcsProcess; |
| 97 | − const legacyGit = yield* makeGitCore(); | |
| 98 | 104 | const capabilities = { |
| 99 | 105 | kind: "git" as const, |
| 100 | 106 | supportsWorktrees: true, |
| @@ -243,7 +249,6 @@ export const make = Effect.fn("makeGitVcsDriver")(function* () { · 142 unmodified lines | ||
| 243 | 249 | ); |
| 244 | 250 | |
| 245 | 251 | return VcsDriver.of({ |
| 246 | − ...legacyGit, | |
| 247 | 252 | capabilities, |
| 248 | 253 | execute, |
| 249 | 254 | detectRepository, |
| @@ -253,4 +258,10 @@ export const make = Effect.fn("makeGitVcsDriver")(function* () { · 3 unmodified lines | ||
| 253 | 258 | }); |
| 254 | 259 | }); |
| 255 | 260 | |
| 256 | −export const layer = Layer.effect(VcsDriver, make()); | |
| 261 | +export const make = Effect.fn("makeGitVcsDriverService")(function* () { | |
| 262 | + const legacyGit = yield* makeGitCore(); | |
| 263 | + return GitVcsDriver.of(legacyGit); | |
| 264 | +}); | |
| 265 | + | |
| 266 | +export const vcsLayer = Layer.effect(VcsDriver, makeVcsDriver()); | |
| 267 | +export const layer = Layer.effect(GitVcsDriver, make()); | |
| @@ -6,10 +6,9 @@ import type { · 5 unmodified lines | ||
| 6 | 6 | VcsListWorkspaceFilesResult, |
| 7 | 7 | VcsRepositoryIdentity, |
| 8 | 8 | } from "@t3tools/contracts"; |
| 9 | −import type { GitCoreShape } from "../git/Services/GitCore.ts"; | |
| 10 | 9 | import type { VcsProcessInput, VcsProcessOutput } from "./VcsProcess.ts"; |
| 11 | 10 | |
| 12 | −export interface VcsDriverShape extends Omit<GitCoreShape, "execute"> { | |
| 11 | +export interface VcsDriverShape { | |
| 13 | 12 | readonly capabilities: VcsDriverCapabilities; |
| 14 | 13 | readonly execute: ( |
| 15 | 14 | input: Omit<VcsProcessInput, "command">, |
| @@ -15,7 +15,7 @@ const TestLayer = Layer.empty.pipe( · 14 unmodified lines | ||
| 15 | 15 | Layer.provideMerge(WorkspaceEntriesLive.pipe(Layer.provide(WorkspacePathsLive))), |
| 16 | 16 | Layer.provideMerge(WorkspacePathsLive), |
| 17 | 17 | Layer.provideMerge(VcsProcess.layer), |
| 18 | − Layer.provideMerge(GitVcsDriver.layer.pipe(Layer.provide(VcsProcess.layer))), | |
| 18 | + Layer.provideMerge(GitVcsDriver.vcsLayer.pipe(Layer.provide(VcsProcess.layer))), | |
| 19 | 19 | Layer.provide( |
| 20 | 20 | ServerConfig.layerTest(process.cwd(), { |
| 21 | 21 | prefix: "t3-workspace-entries-test-", |
| @@ -20,7 +20,7 @@ const TestLayer = Layer.empty.pipe( · 19 unmodified lines | ||
| 20 | 20 | Layer.provideMerge(ProjectLayer), |
| 21 | 21 | Layer.provideMerge(WorkspaceEntriesLive.pipe(Layer.provide(WorkspacePathsLive))), |
| 22 | 22 | Layer.provideMerge(WorkspacePathsLive), |
| 23 | − Layer.provideMerge(GitVcsDriver.layer.pipe(Layer.provide(VcsProcess.layer))), | |
| 23 | + Layer.provideMerge(GitVcsDriver.vcsLayer.pipe(Layer.provide(VcsProcess.layer))), | |
| 24 | 24 | Layer.provide( |
| 25 | 25 | ServerConfig.layerTest(process.cwd(), { |
| 26 | 26 | prefix: "t3-workspace-files-test-", |
| @@ -49,7 +49,7 @@ import { TerminalManager } from "./terminal/Services/Manager.ts"; · 48 unmodified lines | ||
| 49 | 49 | import { WorkspaceEntries } from "./workspace/Services/WorkspaceEntries.ts"; |
| 50 | 50 | import { WorkspaceFileSystem } from "./workspace/Services/WorkspaceFileSystem.ts"; |
| 51 | 51 | import { WorkspacePathOutsideRootError } from "./workspace/Services/WorkspacePaths.ts"; |
| 52 | −import { VcsDriver } from "./vcs/VcsDriver.ts"; | |
| 52 | +import { GitVcsDriver } from "./vcs/GitVcsDriver.ts"; | |
| 53 | 53 | import { ProjectSetupScriptRunner } from "./project/Services/ProjectSetupScriptRunner.ts"; |
| 54 | 54 | import { RepositoryIdentityResolver } from "./project/Services/RepositoryIdentityResolver.ts"; |
| 55 | 55 | import { ServerEnvironment } from "./environment/Services/ServerEnvironment.ts"; |
| @@ -137,7 +137,7 @@ const makeWsRpcLayer = (currentSessionId: AuthSessionId) => · 81 unmodified lines | ||
| 137 | 137 | const keybindings = yield* Keybindings; |
| 138 | 138 | const open = yield* Open; |
| 139 | 139 | const gitManager = yield* GitManager; |
| 140 | − const git = yield* VcsDriver; | |
| 140 | + const git = yield* GitVcsDriver; | |
| 141 | 141 | const gitStatusBroadcaster = yield* GitStatusBroadcaster; |
| 142 | 142 | const terminalManager = yield* TerminalManager; |
| 143 | 143 | const providerRegistry = yield* ProviderRegistry; |