From 28f11ed7a5a2251ebe4689643b64425760ee5fe4 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Fri, 9 Oct 2026 14:49:59 -0700 Subject: [PATCH] refactor(source-control): add @t3tools/source-control-core (#17573) Co-authored-by: Claude Opus 5.5 --- apps/server/package.json | 1 + apps/server/scripts/evaluate-thread-titles.ts | 2 + apps/server/scripts/measure-pr-preview.ts | 2 +- apps/server/src/git/GitManager.test.ts | 2 +- .../PullRequestSyncReactor.test.ts | 2 +- .../PullRequestSyncReactor.ts | 2 +- .../PullRequestWatchReactor.ts | 2 +- .../src/orchestration-v2/runtimeLayer.test.ts | 2 +- .../pullRequest/AzureDevOpsPullRequestCli.ts | 2 +- .../AzureDevOpsPullRequestProvider.ts | 2 +- .../pullRequest/BitbucketPullRequestApi.ts | 2 +- .../BitbucketPullRequestProvider.ts | 2 +- .../pullRequest/ForgejoPullRequestProvider.ts | 2 +- .../pullRequest/GitHubPullRequestApi.test.ts | 2 +- .../src/pullRequest/GitHubPullRequestApi.ts | 9 ++- .../pullRequest/GitHubPullRequestProvider.ts | 2 +- .../src/pullRequest/GitLabPullRequestCli.ts | 2 +- .../pullRequest/GitLabPullRequestProvider.ts | 2 +- .../PullRequestProviderRateLimit.test.ts | 2 +- .../PullRequestProviderRegistry.ts | 2 +- .../pullRequest/PullRequestService.test.ts | 4 +- .../src/pullRequest/PullRequestService.ts | 4 +- .../pullRequest/bitbucketPullRequestJson.ts | 2 +- .../src/pullRequest/forgejoPullRequestJson.ts | 4 +- .../pullRequest/gitHubConditionalChecks.ts | 2 +- .../src/pullRequest/gitHubPullRequestJson.ts | 2 +- .../src/pullRequest/pullRequestViewedFiles.ts | 5 +- apps/server/src/server.ts | 4 +- .../src/sourceControl/AzureDevOpsCli.ts | 2 +- .../AzureDevOpsSourceControlProvider.ts | 4 +- apps/server/src/sourceControl/BitbucketApi.ts | 4 +- .../BitbucketSourceControlProvider.ts | 4 +- apps/server/src/sourceControl/ForgejoCli.ts | 2 +- .../ForgejoSourceControlProvider.ts | 4 +- .../src/sourceControl/GitHubApi.test.ts | 2 +- apps/server/src/sourceControl/GitHubApi.ts | 2 +- .../GitHubSourceControlProvider.ts | 6 +- apps/server/src/sourceControl/GitLabCli.ts | 2 +- .../GitLabSourceControlProvider.ts | 4 +- .../sourceControl/ServerSourceControlHost.ts | 24 ++++++++ .../SourceControlDiscovery.test.ts | 11 +++- .../sourceControl/SourceControlDiscovery.ts | 2 +- .../SourceControlProviderRegistry.test.ts | 6 ++ .../SourceControlProviderRegistry.ts | 9 +-- .../SourceControlRepositoryService.test.ts | 2 +- .../src/sourceControl/githubQuota.test.ts | 2 +- apps/server/src/sourceControl/githubQuota.ts | 2 +- apps/server/src/ws.ts | 2 + docs/internals/pull-request-file-revisions.md | 2 +- package.json | 2 +- packages/source-control-core/package.json | 48 +++++++++++++++ .../src/server}/PullRequestProvider.ts | 0 .../src/server/SourceControlHost.ts | 59 +++++++++++++++++++ .../src/server}/SourceControlProvider.test.ts | 0 .../src/server}/SourceControlProvider.ts | 2 +- .../server}/SourceControlRateLimit.test.ts | 0 .../src/server}/SourceControlRateLimit.ts | 11 ++-- .../src/server/discovery.ts | 15 +++-- .../src/server}/mergeMessage.test.ts | 0 .../src/server}/mergeMessage.ts | 0 .../src/server}/pullRequestChecks.test.ts | 0 .../src/server}/pullRequestChecks.ts | 0 packages/source-control-core/tsconfig.json | 7 +++ pnpm-lock.yaml | 22 +++++++ scripts/release-smoke.ts | 1 + 65 files changed, 268 insertions(+), 70 deletions(-) create mode 100644 apps/server/src/sourceControl/ServerSourceControlHost.ts create mode 100644 packages/source-control-core/package.json rename {apps/server/src/pullRequest => packages/source-control-core/src/server}/PullRequestProvider.ts (100%) create mode 100644 packages/source-control-core/src/server/SourceControlHost.ts rename {apps/server/src/sourceControl => packages/source-control-core/src/server}/SourceControlProvider.test.ts (100%) rename {apps/server/src/sourceControl => packages/source-control-core/src/server}/SourceControlProvider.ts (98%) rename {apps/server/src/sourceControl => packages/source-control-core/src/server}/SourceControlRateLimit.test.ts (100%) rename {apps/server/src/sourceControl => packages/source-control-core/src/server}/SourceControlRateLimit.ts (95%) rename apps/server/src/sourceControl/SourceControlProviderDiscovery.ts => packages/source-control-core/src/server/discovery.ts (95%) rename {apps/server/src/pullRequest => packages/source-control-core/src/server}/mergeMessage.test.ts (100%) rename {apps/server/src/pullRequest => packages/source-control-core/src/server}/mergeMessage.ts (100%) rename {apps/server/src/pullRequest => packages/source-control-core/src/server}/pullRequestChecks.test.ts (100%) rename {apps/server/src/pullRequest => packages/source-control-core/src/server}/pullRequestChecks.ts (100%) create mode 100644 packages/source-control-core/tsconfig.json diff --git a/apps/server/package.json b/apps/server/package.json index bb166039abd95cb1e49908ad61bf46526b7ac532..ea7b9019e41524976f105e6248587af1872518b5 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -45,6 +45,7 @@ "@t3tools/provider-muse": "workspace:*", "@t3tools/provider-opencode": "workspace:*", "@t3tools/provider-pi": "workspace:*", + "@t3tools/source-control-core": "workspace:*", "diff": "8.0.3", "effect": "catalog:", "jose": "catalog:", diff --git a/apps/server/scripts/evaluate-thread-titles.ts b/apps/server/scripts/evaluate-thread-titles.ts index 0747825dcb5b33fc137b0d05ebc51e784a29f10f..196bcbdfbcaaa6169b8a5088cde6ba2697387f9e 100644 --- a/apps/server/scripts/evaluate-thread-titles.ts +++ b/apps/server/scripts/evaluate-thread-titles.ts @@ -23,6 +23,7 @@ import { } from "@t3tools/provider-core/server/threadTitleContext"; import * as ThreadTitleLinks from "../src/textGeneration/ThreadTitleLinks.ts"; import * as SourceControlProviderRegistry from "../src/sourceControl/SourceControlProviderRegistry.ts"; +import * as ServerSourceControlHost from "../src/sourceControl/ServerSourceControlHost.ts"; import * as GitHubApi from "../src/sourceControl/GitHubApi.ts"; import * as GitLabCli from "../src/sourceControl/GitLabCli.ts"; import * as ForgejoCli from "../src/sourceControl/ForgejoCli.ts"; @@ -158,6 +159,7 @@ await Effect.runPromise( AzureDevOpsCli.layer, // No saved credentials here; Bitbucket falls back to T3CODE_BITBUCKET_* variables. BitbucketApi.layer, + ServerSourceControlHost.layer, ), ), // Default settings: no saved Bitbucket token, gh's own GitHub account choice. diff --git a/apps/server/scripts/measure-pr-preview.ts b/apps/server/scripts/measure-pr-preview.ts index e8f0727ac93cf4fb2d2e8ffe26adb39b6e34b770..0f33ec9a6139c05d476781693d92b46c72dd1509 100644 --- a/apps/server/scripts/measure-pr-preview.ts +++ b/apps/server/scripts/measure-pr-preview.ts @@ -16,7 +16,7 @@ import * as GitHubApi from "../src/sourceControl/GitHubApi.ts"; import * as GitHubCredentials from "../src/sourceControl/GitHubCredentials.ts"; import * as ServerSettings from "../src/serverSettings.ts"; import * as GitHubQuota from "../src/sourceControl/githubQuota.ts"; -import * as SourceControlRateLimit from "../src/sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import * as VcsProcess from "../src/vcs/VcsProcess.ts"; const [repository, ...numbers] = process.argv.slice(2); diff --git a/apps/server/src/git/GitManager.test.ts b/apps/server/src/git/GitManager.test.ts index 9f5f368d2cf248d15644794322c6f254507edc5f..c7e76f5e71ab5011eada6a7541ac7cb8817d9a1b 100644 --- a/apps/server/src/git/GitManager.test.ts +++ b/apps/server/src/git/GitManager.test.ts @@ -58,7 +58,7 @@ import { ForgejoPullRequestSchema, toForgejoChangeRequest, } from "../sourceControl/forgejoPullRequests.ts"; -import type { SourceControlProvider } from "../sourceControl/SourceControlProvider.ts"; +import type { SourceControlProvider } from "@t3tools/source-control-core/server/SourceControlProvider"; import * as SourceControlProviderRegistry from "../sourceControl/SourceControlProviderRegistry.ts"; import * as ServerConfig from "../config.ts"; import * as ProjectionStore from "../orchestration-v2/ProjectionStore.ts"; diff --git a/apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts b/apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts index 36f4bdb158913f84d12a8c6f6e5ccc8775dc11c9..19e67f949b611104f5517c23fb8192c59dc2a4e4 100644 --- a/apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts +++ b/apps/server/src/orchestration-v2/PullRequestSyncReactor.test.ts @@ -31,7 +31,7 @@ import * as Queue from "effect/Queue"; import * as Ref from "effect/Ref"; import { TestClock } from "effect/testing"; -import { PullRequestProviderError } from "../pullRequest/PullRequestProvider.ts"; +import { PullRequestProviderError } from "@t3tools/source-control-core/server/PullRequestProvider"; import * as GitManager from "../git/GitManager.ts"; import * as PullRequestService from "../pullRequest/PullRequestService.ts"; import * as ServerActivation from "../serverActivation.ts"; diff --git a/apps/server/src/orchestration-v2/PullRequestSyncReactor.ts b/apps/server/src/orchestration-v2/PullRequestSyncReactor.ts index 5f1fcd8269acd4c42c8f1b0903ec075ea17ff421..a966cbd954561dac945e572e4c9d8f290242279f 100644 --- a/apps/server/src/orchestration-v2/PullRequestSyncReactor.ts +++ b/apps/server/src/orchestration-v2/PullRequestSyncReactor.ts @@ -29,7 +29,7 @@ import * as Semaphore from "effect/Semaphore"; import * as Stream from "effect/Stream"; import * as GitManager from "../git/GitManager.ts"; -import { PullRequestProviderError } from "../pullRequest/PullRequestProvider.ts"; +import { PullRequestProviderError } from "@t3tools/source-control-core/server/PullRequestProvider"; import * as PullRequestService from "../pullRequest/PullRequestService.ts"; import { forkParked } from "../serverActivation.ts"; import * as Orchestrator from "./Orchestrator.ts"; diff --git a/apps/server/src/orchestration-v2/PullRequestWatchReactor.ts b/apps/server/src/orchestration-v2/PullRequestWatchReactor.ts index 7005534f89edee4aa792019bf50dde60896be58e..5a5f61ae3c4da8ca89eca2bd8988710d58e02508 100644 --- a/apps/server/src/orchestration-v2/PullRequestWatchReactor.ts +++ b/apps/server/src/orchestration-v2/PullRequestWatchReactor.ts @@ -29,7 +29,7 @@ import type * as Scope from "effect/Scope"; import { type ProviderChangeRequestWatchFingerprint, PullRequestProviderError, -} from "../pullRequest/PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import * as PullRequestService from "../pullRequest/PullRequestService.ts"; import { forkParked } from "../serverActivation.ts"; import * as Orchestrator from "./Orchestrator.ts"; diff --git a/apps/server/src/orchestration-v2/runtimeLayer.test.ts b/apps/server/src/orchestration-v2/runtimeLayer.test.ts index b11184f4463262a8e2d078f28d53cd41049c0191..bb70c880b061554779ccc0a47e4ef3e4e9078c25 100644 --- a/apps/server/src/orchestration-v2/runtimeLayer.test.ts +++ b/apps/server/src/orchestration-v2/runtimeLayer.test.ts @@ -65,7 +65,7 @@ import * as ProviderRuntimeRecoveryService from "./ProviderRuntimeRecoveryServic import * as ProjectionMaintenance from "./ProjectionMaintenance.ts"; import * as ProjectionStore from "./ProjectionStore.ts"; import * as PullRequestWatchReactor from "./PullRequestWatchReactor.ts"; -import { PullRequestProviderError } from "../pullRequest/PullRequestProvider.ts"; +import { PullRequestProviderError } from "@t3tools/source-control-core/server/PullRequestProvider"; import * as PullRequestService from "../pullRequest/PullRequestService.ts"; import * as ProjectStore from "./ProjectStore.ts"; import * as ProviderSessionManager from "./ProviderSessionManager.ts"; diff --git a/apps/server/src/pullRequest/AzureDevOpsPullRequestCli.ts b/apps/server/src/pullRequest/AzureDevOpsPullRequestCli.ts index 5f5453a9b3badf8cd9f0d8b1d78f3190ed4cac07..d00d08b7d05f7649044270ff9bd33599db3b8bf1 100644 --- a/apps/server/src/pullRequest/AzureDevOpsPullRequestCli.ts +++ b/apps/server/src/pullRequest/AzureDevOpsPullRequestCli.ts @@ -26,7 +26,7 @@ import { type AzureDevOpsPullRequest, type AzureDevOpsRepositoryLocation, } from "./azureDevOpsPullRequestJson.ts"; -import type { ProviderListCursor } from "./PullRequestProvider.ts"; +import type { ProviderListCursor } from "@t3tools/source-control-core/server/PullRequestProvider"; /** * Names the read that produced unusable output, so a failure reports the call it came from diff --git a/apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts b/apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts index 2cdf78c56a1456a264fdad465833c3d7384d0c33..afd0456369473ec9bdbd53f61673d4f7c672c3b6 100644 --- a/apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts +++ b/apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts @@ -24,7 +24,7 @@ import { type ProviderChangeRequestSummary, type ProviderDiffSlice, type PullRequestProviderApi, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import type { AzureDevOpsChangeEntry, AzureDevOpsItemContent, diff --git a/apps/server/src/pullRequest/BitbucketPullRequestApi.ts b/apps/server/src/pullRequest/BitbucketPullRequestApi.ts index c7d017071fc61fc54283fc2590ffcdc57db7fafa..f5e108b05d452941b3135a0b07e88f1518b65c9b 100644 --- a/apps/server/src/pullRequest/BitbucketPullRequestApi.ts +++ b/apps/server/src/pullRequest/BitbucketPullRequestApi.ts @@ -39,7 +39,7 @@ import { type BitbucketPullRequest, type BitbucketRawComment, } from "./bitbucketPullRequestJson.ts"; -import type { ProviderListCursor } from "./PullRequestProvider.ts"; +import type { ProviderListCursor } from "@t3tools/source-control-core/server/PullRequestProvider"; /** * Names the read that produced unusable output, so a failure reports the call it came from diff --git a/apps/server/src/pullRequest/BitbucketPullRequestProvider.ts b/apps/server/src/pullRequest/BitbucketPullRequestProvider.ts index f553dfd13bc1a23a4518181ecb8832d447b2fe80..0abcb7d95e7e745350044265fea70c145aae5fba 100644 --- a/apps/server/src/pullRequest/BitbucketPullRequestProvider.ts +++ b/apps/server/src/pullRequest/BitbucketPullRequestProvider.ts @@ -9,7 +9,7 @@ import { type ProviderChangeRequestActivity, type ProviderChangeRequestDetail, type PullRequestProviderApi, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import type { BitbucketPullRequest } from "./bitbucketPullRequestJson.ts"; const CAPABILITIES: PullRequestCapabilities = { diff --git a/apps/server/src/pullRequest/ForgejoPullRequestProvider.ts b/apps/server/src/pullRequest/ForgejoPullRequestProvider.ts index 12d931279a74c4644f31acc3363a4f3a56955857..a9337fdbe8fd46c2b5b67051aaca746a35f8fad2 100644 --- a/apps/server/src/pullRequest/ForgejoPullRequestProvider.ts +++ b/apps/server/src/pullRequest/ForgejoPullRequestProvider.ts @@ -10,7 +10,7 @@ import { type ProviderChangeRequestDetail, type ProviderRepositoryRef, type PullRequestProviderApi, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import { ForgejoPullRequest, ForgejoRepository, diff --git a/apps/server/src/pullRequest/GitHubPullRequestApi.test.ts b/apps/server/src/pullRequest/GitHubPullRequestApi.test.ts index 294d053d6f056d88426a7bc1b572af95c0d6f662..8888f4c11f45a2310dfda82bc1a9829d940abb4c 100644 --- a/apps/server/src/pullRequest/GitHubPullRequestApi.test.ts +++ b/apps/server/src/pullRequest/GitHubPullRequestApi.test.ts @@ -16,7 +16,7 @@ import { AllowGitHubReserve } from "../sourceControl/GitHubApi.ts"; import * as GitHubApi from "../sourceControl/GitHubApi.ts"; import * as GitHubCredentials from "../sourceControl/GitHubCredentials.ts"; import * as GitHubQuota from "../sourceControl/githubQuota.ts"; -import * as SourceControlRateLimit from "../sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import * as VcsProcess from "../vcs/VcsProcess.ts"; import * as GitHubPullRequestApi from "./GitHubPullRequestApi.ts"; import { KnownWorkflowRuns } from "./gitHubConditionalChecks.ts"; diff --git a/apps/server/src/pullRequest/GitHubPullRequestApi.ts b/apps/server/src/pullRequest/GitHubPullRequestApi.ts index 5e35729154604a3cfe5efd1f6865a1179ac2bd45..dd093df00b775ea32223af3eef936a30418c7f0f 100644 --- a/apps/server/src/pullRequest/GitHubPullRequestApi.ts +++ b/apps/server/src/pullRequest/GitHubPullRequestApi.ts @@ -1,4 +1,4 @@ -import { removeAgentCredits } from "./mergeMessage.ts"; +import { removeAgentCredits } from "@t3tools/source-control-core/server/mergeMessage"; import { KnownWorkflowRuns, makeChecksRevalidator } from "./gitHubConditionalChecks.ts"; import { runGitHubStackAction, type GitHubStackActionError } from "./githubStackActions.ts"; import * as Cause from "effect/Cause"; @@ -45,7 +45,7 @@ import { import * as GitHubApi from "../sourceControl/GitHubApi.ts"; import { readGraphQlPages } from "../sourceControl/githubGraphQl.ts"; import * as VcsProcess from "../vcs/VcsProcess.ts"; -import * as SourceControlRateLimit from "../sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import { ACTOR_AVATARS_GRAPHQL_QUERY, ADD_REACTION_GRAPHQL_MUTATION, @@ -128,7 +128,10 @@ import { type GitHubReviewThreadPage, type GitHubViewerAccess, } from "./gitHubPullRequestJson.ts"; -import type { ProviderChangeRequestSummary, ProviderListCursor } from "./PullRequestProvider.ts"; +import type { + ProviderChangeRequestSummary, + ProviderListCursor, +} from "@t3tools/source-control-core/server/PullRequestProvider"; /** * Names the read that produced unusable output, so a failure reports the call it came from diff --git a/apps/server/src/pullRequest/GitHubPullRequestProvider.ts b/apps/server/src/pullRequest/GitHubPullRequestProvider.ts index f2672dbe991fde29f668c872b4a9487523104601..67f871501ddb2af74eb06c6214c4f4905bcd4145 100644 --- a/apps/server/src/pullRequest/GitHubPullRequestProvider.ts +++ b/apps/server/src/pullRequest/GitHubPullRequestProvider.ts @@ -16,7 +16,7 @@ import { type ProviderChangeRequestDetail, type PullRequestProviderApi, type ProviderRepositoryRef, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import type { GitHubViewerAccess, GitHubWorkflowRunApproval } from "./gitHubPullRequestJson.ts"; const CAPABILITIES: PullRequestCapabilities = { diff --git a/apps/server/src/pullRequest/GitLabPullRequestCli.ts b/apps/server/src/pullRequest/GitLabPullRequestCli.ts index c3b6070024978a013025490cd22301b21a11894a..933e6874218737dae99bb852194175a524be8326 100644 --- a/apps/server/src/pullRequest/GitLabPullRequestCli.ts +++ b/apps/server/src/pullRequest/GitLabPullRequestCli.ts @@ -44,7 +44,7 @@ import { type GitLabMergeRequestListItem, type GitLabProjectUsers, } from "./gitLabMergeRequestJson.ts"; -import type { ProviderListCursor } from "./PullRequestProvider.ts"; +import type { ProviderListCursor } from "@t3tools/source-control-core/server/PullRequestProvider"; /** * Names the read that produced unusable output, so a failure reports the call it came from diff --git a/apps/server/src/pullRequest/GitLabPullRequestProvider.ts b/apps/server/src/pullRequest/GitLabPullRequestProvider.ts index 45034b84787c3210c69bb603a7d71800a06e64bb..1b5b987cd5acb3c25dc6fd8f080b703c6a07d6c9 100644 --- a/apps/server/src/pullRequest/GitLabPullRequestProvider.ts +++ b/apps/server/src/pullRequest/GitLabPullRequestProvider.ts @@ -12,7 +12,7 @@ import { type ProviderChangeRequestActivity, type ProviderChangeRequestDetail, type PullRequestProviderApi, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; const CAPABILITIES: PullRequestCapabilities = { diff: true, diff --git a/apps/server/src/pullRequest/PullRequestProviderRateLimit.test.ts b/apps/server/src/pullRequest/PullRequestProviderRateLimit.test.ts index 873cc32a2c7f102cdd34046d16c2f9167b790a23..ca12da2b8979113bd8561c445da87d99b277db77 100644 --- a/apps/server/src/pullRequest/PullRequestProviderRateLimit.test.ts +++ b/apps/server/src/pullRequest/PullRequestProviderRateLimit.test.ts @@ -3,7 +3,7 @@ import { assert, it } from "@effect/vitest"; import * as AzureDevOpsCli from "../sourceControl/AzureDevOpsCli.ts"; import * as BitbucketApi from "../sourceControl/BitbucketApi.ts"; import * as GitHubApi from "../sourceControl/GitHubApi.ts"; -import * as SourceControlRateLimit from "../sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import * as GitLabCli from "../sourceControl/GitLabCli.ts"; import { azureDevOpsProviderFailure } from "./AzureDevOpsPullRequestProvider.ts"; import { bitbucketProviderFailure } from "./BitbucketPullRequestProvider.ts"; diff --git a/apps/server/src/pullRequest/PullRequestProviderRegistry.ts b/apps/server/src/pullRequest/PullRequestProviderRegistry.ts index 316cd1e7ae92f37d90f5153950dae544a8df8a18..8e5a1d9cfd0b008d3e3e4290c3bb8358f576afb4 100644 --- a/apps/server/src/pullRequest/PullRequestProviderRegistry.ts +++ b/apps/server/src/pullRequest/PullRequestProviderRegistry.ts @@ -17,7 +17,7 @@ import * as GitHubPullRequestApi from "./GitHubPullRequestApi.ts"; import * as GitHubPullRequestProvider from "./GitHubPullRequestProvider.ts"; import * as GitLabPullRequestCli from "./GitLabPullRequestCli.ts"; import * as GitLabPullRequestProvider from "./GitLabPullRequestProvider.ts"; -import type { PullRequestProviderApi } from "./PullRequestProvider.ts"; +import type { PullRequestProviderApi } from "@t3tools/source-control-core/server/PullRequestProvider"; export class PullRequestProviderRegistry extends Context.Service< PullRequestProviderRegistry, diff --git a/apps/server/src/pullRequest/PullRequestService.test.ts b/apps/server/src/pullRequest/PullRequestService.test.ts index f9015ecbd9ef83781d35b290a1af728424b1ecf9..ef84de264ec63216f4ff63c6beec602c5099319a 100644 --- a/apps/server/src/pullRequest/PullRequestService.test.ts +++ b/apps/server/src/pullRequest/PullRequestService.test.ts @@ -29,14 +29,14 @@ import * as SqlitePersistence from "../persistence/Sqlite.ts"; import * as PullRequestFilesViewed from "../persistence/PullRequestFilesViewed.ts"; import * as RepositoryIdentityResolver from "../project/RepositoryIdentityResolver.ts"; import * as SourceControlProviderRegistry from "../sourceControl/SourceControlProviderRegistry.ts"; -import * as SourceControlRateLimit from "../sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import * as ForgejoCli from "../sourceControl/ForgejoCli.ts"; import * as ForgejoPullRequestProvider from "./ForgejoPullRequestProvider.ts"; import { PullRequestProviderError, type ProviderChangeRequest, type PullRequestProviderApi, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import * as PullRequestProviderRegistry from "./PullRequestProviderRegistry.ts"; import * as PullRequestService from "./PullRequestService.ts"; import * as PullRequestReadCache from "./PullRequestReadCache.ts"; diff --git a/apps/server/src/pullRequest/PullRequestService.ts b/apps/server/src/pullRequest/PullRequestService.ts index a44bd322adcba8db5f9dc103d380ac3c121a2869..fb14ef896cd51a3721ee56db7c6fe35adc229e53 100644 --- a/apps/server/src/pullRequest/PullRequestService.ts +++ b/apps/server/src/pullRequest/PullRequestService.ts @@ -83,14 +83,14 @@ import * as ServerSettings from "../serverSettings.ts"; import * as PullRequestFilesViewed from "../persistence/PullRequestFilesViewed.ts"; import * as RepositoryIdentityResolver from "../project/RepositoryIdentityResolver.ts"; import * as SourceControlProviderRegistry from "../sourceControl/SourceControlProviderRegistry.ts"; -import * as SourceControlRateLimit from "../sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import { type ProviderChangeRequest, type ProviderListCursor, type ProviderChangeRequestWatchFingerprint, type PullRequestProviderApi, PullRequestProviderError, -} from "./PullRequestProvider.ts"; +} from "@t3tools/source-control-core/server/PullRequestProvider"; import * as PullRequestReadCache from "./PullRequestReadCache.ts"; import * as PullRequestProviderRegistry from "./PullRequestProviderRegistry.ts"; import * as ViewedFiles from "./pullRequestViewedFiles.ts"; diff --git a/apps/server/src/pullRequest/bitbucketPullRequestJson.ts b/apps/server/src/pullRequest/bitbucketPullRequestJson.ts index f0bc8a71a82704afb6e38229ed05cc6aff78d69d..8f0b520ca089b64d6851b8c1bd8e159964ac48b1 100644 --- a/apps/server/src/pullRequest/bitbucketPullRequestJson.ts +++ b/apps/server/src/pullRequest/bitbucketPullRequestJson.ts @@ -18,7 +18,7 @@ import type { import { TrimmedNonEmptyString } from "@t3tools/contracts"; import { decodeJsonResult } from "@t3tools/shared/schemaJson"; -import { dedupeChecks } from "./pullRequestChecks.ts"; +import { dedupeChecks } from "@t3tools/source-control-core/server/pullRequestChecks"; /** * Bitbucket's enums are decoded as plain strings and normalized here, in the same tolerant diff --git a/apps/server/src/pullRequest/forgejoPullRequestJson.ts b/apps/server/src/pullRequest/forgejoPullRequestJson.ts index cade3b65d9c8389d27b818b2e5ee6a916b4f489f..a937c00c2ef842a273f0b20d70c0bd1caded6e0b 100644 --- a/apps/server/src/pullRequest/forgejoPullRequestJson.ts +++ b/apps/server/src/pullRequest/forgejoPullRequestJson.ts @@ -10,8 +10,8 @@ import type { PullRequestReactionContent, PullRequestReviewThread, } from "@t3tools/contracts"; -import type { ProviderChangeRequest } from "./PullRequestProvider.ts"; -import { dedupeChecks } from "./pullRequestChecks.ts"; +import type { ProviderChangeRequest } from "@t3tools/source-control-core/server/PullRequestProvider"; +import { dedupeChecks } from "@t3tools/source-control-core/server/pullRequestChecks"; export const ForgejoUser = Schema.Struct({ login: Schema.String, diff --git a/apps/server/src/pullRequest/gitHubConditionalChecks.ts b/apps/server/src/pullRequest/gitHubConditionalChecks.ts index 6975da251936bbab015b8544e033ece84e8f4452..353089ebf0f9648d0156fdbb1304bd2f0722a0fc 100644 --- a/apps/server/src/pullRequest/gitHubConditionalChecks.ts +++ b/apps/server/src/pullRequest/gitHubConditionalChecks.ts @@ -10,7 +10,7 @@ import { PositiveInt, type PullRequestChecks } from "@t3tools/contracts"; import * as GitHubApi from "../sourceControl/GitHubApi.ts"; import type { GitHubPullRequestDetail } from "./gitHubPullRequestJson.ts"; import type { GitHubPullRequestApiError } from "./GitHubPullRequestApi.ts"; -import type { ProviderRepositoryRef } from "./PullRequestProvider.ts"; +import type { ProviderRepositoryRef } from "@t3tools/source-control-core/server/PullRequestProvider"; const HeadSchema = Schema.Struct({ head: Schema.Struct({ diff --git a/apps/server/src/pullRequest/gitHubPullRequestJson.ts b/apps/server/src/pullRequest/gitHubPullRequestJson.ts index 028231c513f24219c7e86447e00a7b851e10be5d..edca11f5a0d082ab4a0bec2e4d000ad0aa649418 100644 --- a/apps/server/src/pullRequest/gitHubPullRequestJson.ts +++ b/apps/server/src/pullRequest/gitHubPullRequestJson.ts @@ -36,7 +36,7 @@ import { quoteGitPatchPath } from "@t3tools/shared/gitPatchPath"; import { decodeJsonResult } from "@t3tools/shared/schemaJson"; import { aliasedGraphQlDocument, type GraphQlDocument } from "../sourceControl/githubGraphQl.ts"; -import { dedupeChecks } from "./pullRequestChecks.ts"; +import { dedupeChecks } from "@t3tools/source-control-core/server/pullRequestChecks"; /** * Enum-ish GitHub CLI fields are decoded as plain strings and normalized here: a `gh` diff --git a/apps/server/src/pullRequest/pullRequestViewedFiles.ts b/apps/server/src/pullRequest/pullRequestViewedFiles.ts index 1f9aa33ac796e67c19a5c0058e53df67e3297172..9f64c8352af54edda29f3fa195ea14f23f127757 100644 --- a/apps/server/src/pullRequest/pullRequestViewedFiles.ts +++ b/apps/server/src/pullRequest/pullRequestViewedFiles.ts @@ -16,7 +16,10 @@ import { } from "@t3tools/contracts"; import type * as PullRequestFilesViewed from "../persistence/PullRequestFilesViewed.ts"; -import type { ProviderFileRevisions, PullRequestProviderError } from "./PullRequestProvider.ts"; +import type { + ProviderFileRevisions, + PullRequestProviderError, +} from "@t3tools/source-control-core/server/PullRequestProvider"; import type { PullRequestError, SupportedProject } from "./PullRequestService.ts"; /** diff --git a/apps/server/src/server.ts b/apps/server/src/server.ts index 1bbe647dcd0cf5599b3c6bfbf79e75b0dd38cb0c..913f8067d250df07aeb2a73fb281488edf74f941 100644 --- a/apps/server/src/server.ts +++ b/apps/server/src/server.ts @@ -104,8 +104,9 @@ import * as ProjectCloneTracker from "./project/ProjectCloneTracker.ts"; import * as GitWorkflowService from "./git/GitWorkflowService.ts"; import * as ReviewService from "./review/ReviewService.ts"; import * as SourceControlProviderRegistry from "./sourceControl/SourceControlProviderRegistry.ts"; +import * as ServerSourceControlHost from "./sourceControl/ServerSourceControlHost.ts"; import * as PullRequestReadCache from "./pullRequest/PullRequestReadCache.ts"; -import * as SourceControlRateLimit from "./sourceControl/SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import * as SourceControlRepositoryService from "./sourceControl/SourceControlRepositoryService.ts"; import * as WorktreeSetupTracker from "./project/WorktreeSetupTracker.ts"; import * as Observability from "./observability/Observability.ts"; @@ -305,6 +306,7 @@ const layerSourceControlProviderRegistry = SourceControlProviderRegistry.layer.p GitHubApi.layerWithDependencies, GitLabCli.layer, ForgejoCli.layer, + ServerSourceControlHost.layer, ), ), Layer.provideMerge(GitVcsDriver.layer), diff --git a/apps/server/src/sourceControl/AzureDevOpsCli.ts b/apps/server/src/sourceControl/AzureDevOpsCli.ts index f5e436ef6c564386fbabb86ae1d4ac4a2e872207..7fd44de3c40b9a901329ea61bd98d1f61e5a7882 100644 --- a/apps/server/src/sourceControl/AzureDevOpsCli.ts +++ b/apps/server/src/sourceControl/AzureDevOpsCli.ts @@ -17,7 +17,7 @@ import { decodeAzureDevOpsPullRequestListJson, type NormalizedAzureDevOpsPullRequestRecord, } from "./azureDevOpsPullRequests.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; const DEFAULT_TIMEOUT_MS = 30_000; diff --git a/apps/server/src/sourceControl/AzureDevOpsSourceControlProvider.ts b/apps/server/src/sourceControl/AzureDevOpsSourceControlProvider.ts index c2f6a5efc65ac7ef7977f5bea3b5fddd61195071..dcb07e0632f3c5646f44df552f25c02aaac495e2 100644 --- a/apps/server/src/sourceControl/AzureDevOpsSourceControlProvider.ts +++ b/apps/server/src/sourceControl/AzureDevOpsSourceControlProvider.ts @@ -2,14 +2,14 @@ import * as Effect from "effect/Effect"; import { SourceControlProviderError, type ChangeRequest } from "@t3tools/contracts"; import * as AzureDevOpsCli from "./AzureDevOpsCli.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import { combinedAuthOutput, firstSafeAuthLine, providerAuth, type SourceControlAuthProbeInput, type SourceControlCliDiscoverySpec, -} from "./SourceControlProviderDiscovery.ts"; +} from "@t3tools/source-control-core/server/discovery"; function parseAzureAuth(input: SourceControlAuthProbeInput) { const account = input.stdout.trim().split(/\r?\n/)[0]?.trim(); diff --git a/apps/server/src/sourceControl/BitbucketApi.ts b/apps/server/src/sourceControl/BitbucketApi.ts index fbff83dfedb56e8b68762d7b34dd18bf0e4c785d..f7fa5cc4568c705fb8df0868298ab93c043eda8c 100644 --- a/apps/server/src/sourceControl/BitbucketApi.ts +++ b/apps/server/src/sourceControl/BitbucketApi.ts @@ -29,11 +29,11 @@ import { type NormalizedBitbucketPullRequestRecord, } from "./bitbucketPullRequests.ts"; import { collectUint8StreamText } from "@t3tools/provider-core/server/collectStreamText"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import * as ServerSettings from "../serverSettings.ts"; import * as GitVcsDriver from "../vcs/GitVcsDriver.ts"; import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts"; -import { retryAtFromHeader } from "./SourceControlRateLimit.ts"; +import { retryAtFromHeader } from "@t3tools/source-control-core/server/SourceControlRateLimit"; const DEFAULT_API_BASE_URL = "https://api.bitbucket.org/2.0"; /** A response body past this is cut short, so one huge diff cannot exhaust the server. */ diff --git a/apps/server/src/sourceControl/BitbucketSourceControlProvider.ts b/apps/server/src/sourceControl/BitbucketSourceControlProvider.ts index f1a01056fbd0a879f5fe7e1d0104db4163b7c325..b9afd60bc389657b4d7c0c04decbab9747a69a0c 100644 --- a/apps/server/src/sourceControl/BitbucketSourceControlProvider.ts +++ b/apps/server/src/sourceControl/BitbucketSourceControlProvider.ts @@ -4,8 +4,8 @@ import { SourceControlProviderError, type ChangeRequest } from "@t3tools/contrac import * as BitbucketApi from "./BitbucketApi.ts"; import type { NormalizedBitbucketPullRequestRecord } from "./bitbucketPullRequests.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; -import type { SourceControlApiDiscoverySpec } from "./SourceControlProviderDiscovery.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; +import type { SourceControlApiDiscoverySpec } from "@t3tools/source-control-core/server/discovery"; function toChangeRequest(summary: NormalizedBitbucketPullRequestRecord): ChangeRequest { return { diff --git a/apps/server/src/sourceControl/ForgejoCli.ts b/apps/server/src/sourceControl/ForgejoCli.ts index eb284af237c84b5ef4c883e0f374e12857884ad3..573c081e5a42ae3174d0b0bc17ca11057febc931 100644 --- a/apps/server/src/sourceControl/ForgejoCli.ts +++ b/apps/server/src/sourceControl/ForgejoCli.ts @@ -15,7 +15,7 @@ import { decodeJsonResult } from "@t3tools/shared/schemaJson"; import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; import * as VcsProcess from "../vcs/VcsProcess.ts"; import { collectUint8StreamText } from "@t3tools/provider-core/server/collectStreamText"; -import type { SourceControlProviderContext } from "./SourceControlProvider.ts"; +import type { SourceControlProviderContext } from "@t3tools/source-control-core/server/SourceControlProvider"; const encodeApiBody = Schema.encodeEffect(Schema.fromJsonString(Schema.Unknown)); diff --git a/apps/server/src/sourceControl/ForgejoSourceControlProvider.ts b/apps/server/src/sourceControl/ForgejoSourceControlProvider.ts index 5a501d96b23592b1217b8831a876d1963de2da6f..79a1ca6f2aa030006e104190f0dad5b11f40c049 100644 --- a/apps/server/src/sourceControl/ForgejoSourceControlProvider.ts +++ b/apps/server/src/sourceControl/ForgejoSourceControlProvider.ts @@ -5,13 +5,13 @@ import * as Result from "effect/Result"; import { SourceControlProviderError } from "@t3tools/contracts"; import * as VcsProcess from "../vcs/VcsProcess.ts"; import * as ForgejoCli from "./ForgejoCli.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import { providerAuth, probeSourceControlProvider, type SourceControlCliDiscoverySpec, type SourceControlManagedCliDiscoverySpec, -} from "./SourceControlProviderDiscovery.ts"; +} from "@t3tools/source-control-core/server/discovery"; import { ForgejoPullRequestSchema, toForgejoChangeRequest } from "./forgejoPullRequests.ts"; const isForgejoCliError = Schema.is(ForgejoCli.ForgejoCliError); diff --git a/apps/server/src/sourceControl/GitHubApi.test.ts b/apps/server/src/sourceControl/GitHubApi.test.ts index 60e2c6f1b45d5f4d3653d7c4ccce7dbbce462cdd..cd4c2fb384f230a861c4a953b20965f9df78e059 100644 --- a/apps/server/src/sourceControl/GitHubApi.test.ts +++ b/apps/server/src/sourceControl/GitHubApi.test.ts @@ -13,7 +13,7 @@ import { HttpClient, HttpClientResponse, type HttpClientRequest } from "effect/h import * as GitHubApi from "./GitHubApi.ts"; import * as GitHubCredentials from "./GitHubCredentials.ts"; import * as GitHubQuota from "./githubQuota.ts"; -import * as SourceControlRateLimit from "./SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import * as VcsProcess from "../vcs/VcsProcess.ts"; import * as ServerSettings from "../serverSettings.ts"; diff --git a/apps/server/src/sourceControl/GitHubApi.ts b/apps/server/src/sourceControl/GitHubApi.ts index 5a99cf68943b12fc8a6fde117c6afbeba9ccff19..1cc66a1323c7f42011a64ce924215dffe6f3dc38 100644 --- a/apps/server/src/sourceControl/GitHubApi.ts +++ b/apps/server/src/sourceControl/GitHubApi.ts @@ -13,7 +13,7 @@ import { HttpClient, HttpClientRequest, type HttpClientResponse } from "effect/h import { collectUint8StreamText } from "@t3tools/provider-core/server/collectStreamText"; import * as GitHubCredentials from "./GitHubCredentials.ts"; import * as GitHubQuota from "./githubQuota.ts"; -import * as SourceControlRateLimit from "./SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; const DEFAULT_TIMEOUT = Duration.seconds(30); const DEFAULT_MAX_RESPONSE_BYTES = 8 * 1024 * 1024; diff --git a/apps/server/src/sourceControl/GitHubSourceControlProvider.ts b/apps/server/src/sourceControl/GitHubSourceControlProvider.ts index da3d53330864c31b07b84b41c2a7612998b249e9..35876794048a0eb0751faff02fc62457b1d90876 100644 --- a/apps/server/src/sourceControl/GitHubSourceControlProvider.ts +++ b/apps/server/src/sourceControl/GitHubSourceControlProvider.ts @@ -37,14 +37,14 @@ import { resolveGitHubRepository, type GitHubRepositoryLocator, } from "./gitHubRepositoryResolution.ts"; -import * as SourceControlRateLimit from "./SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; import { effectiveGitHubAccount, findAuthenticatedGitHubAccount, parseGitHubAuthStatus, type GitHubAuthStatusAccount, } from "./gitHubAuthStatus.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import { combinedAuthOutput, firstSafeAuthLine, @@ -53,7 +53,7 @@ import { type SourceControlAuthProbeInput, type SourceControlCliDiscoverySpec, type SourceControlManagedCliDiscoverySpec, -} from "./SourceControlProviderDiscovery.ts"; +} from "@t3tools/source-control-core/server/discovery"; import * as VcsProcess from "../vcs/VcsProcess.ts"; const decodeLinkSubject = Schema.decodeUnknownEffect( diff --git a/apps/server/src/sourceControl/GitLabCli.ts b/apps/server/src/sourceControl/GitLabCli.ts index 9d03e1ab8aa5499a64bdd1d2ac3b150b185ff791..2ec69a527fedffa9f1f78dd0cfa74a8a947992d1 100644 --- a/apps/server/src/sourceControl/GitLabCli.ts +++ b/apps/server/src/sourceControl/GitLabCli.ts @@ -18,7 +18,7 @@ import { decodeGitLabMergeRequestJson, decodeGitLabMergeRequestListJson, } from "./gitLabMergeRequests.ts"; -import type * as SourceControlProvider from "./SourceControlProvider.ts"; +import type * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; const DEFAULT_TIMEOUT_MS = 30_000; diff --git a/apps/server/src/sourceControl/GitLabSourceControlProvider.ts b/apps/server/src/sourceControl/GitLabSourceControlProvider.ts index 00753bef7dea7f13c402b2401105c0556ee990b0..ef63f11cfdf24553ef43de44df9d89d29c0eb77b 100644 --- a/apps/server/src/sourceControl/GitLabSourceControlProvider.ts +++ b/apps/server/src/sourceControl/GitLabSourceControlProvider.ts @@ -4,7 +4,7 @@ import * as Option from "effect/Option"; import { SourceControlProviderError, type ChangeRequest } from "@t3tools/contracts"; import * as GitLabCli from "./GitLabCli.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import { combinedAuthOutput, firstSafeAuthLine, @@ -14,7 +14,7 @@ import { type SourceControlAuthProbeInput, type SourceControlCliDiscoverySpec, type SourceControlUnknownRemoteRefinementInput, -} from "./SourceControlProviderDiscovery.ts"; +} from "@t3tools/source-control-core/server/discovery"; import { findAuthenticatedGitLabHost, parseGitLabAuthStatusHosts } from "./gitLabAuthStatus.ts"; const decodeLinkSubject = Schema.decodeUnknownEffect( diff --git a/apps/server/src/sourceControl/ServerSourceControlHost.ts b/apps/server/src/sourceControl/ServerSourceControlHost.ts new file mode 100644 index 0000000000000000000000000000000000000000..f458795ab76e90c5c69b41cc3cf23fdd0a991669 --- /dev/null +++ b/apps/server/src/sourceControl/ServerSourceControlHost.ts @@ -0,0 +1,24 @@ +/** + * The server's implementation of `SourceControlHost.SourceControlHost`, the only server surface + * source control provider packages may use. + * + * @module sourceControl/ServerSourceControlHost + */ +import * as SourceControlHost from "@t3tools/source-control-core/server/SourceControlHost"; +import * as Effect from "effect/Effect"; +import * as Layer from "effect/Layer"; + +import * as ServerSettings from "../serverSettings.ts"; +import * as VcsProcess from "../vcs/VcsProcess.ts"; + +export const layer = Layer.effect( + SourceControlHost.SourceControlHost, + Effect.gen(function* () { + const serverSettings = yield* ServerSettings.ServerSettingsService; + const process = yield* VcsProcess.VcsProcess; + return SourceControlHost.SourceControlHost.of({ + settings: { get: serverSettings.getSettings }, + process: { run: process.run }, + }); + }), +); diff --git a/apps/server/src/sourceControl/SourceControlDiscovery.test.ts b/apps/server/src/sourceControl/SourceControlDiscovery.test.ts index 6101d148a632740479c58dcc81225934cd642c5d..e0d1c3efca238fdb8a33920212a7fc21c7793308 100644 --- a/apps/server/src/sourceControl/SourceControlDiscovery.test.ts +++ b/apps/server/src/sourceControl/SourceControlDiscovery.test.ts @@ -25,7 +25,8 @@ import * as ForgejoSourceControlProvider from "./ForgejoSourceControlProvider.ts import * as ForgejoPullRequestProvider from "../pullRequest/ForgejoPullRequestProvider.ts"; import * as SourceControlDiscovery from "./SourceControlDiscovery.ts"; import * as SourceControlProviderRegistry from "./SourceControlProviderRegistry.ts"; -import { firstNonEmptyLine } from "./SourceControlProviderDiscovery.ts"; +import * as ServerSourceControlHost from "./ServerSourceControlHost.ts"; +import { firstNonEmptyLine } from "@t3tools/source-control-core/server/discovery"; const layerSourceControlProviderRegistryTest = (input: { readonly bitbucket: Partial; @@ -46,6 +47,14 @@ const layerSourceControlProviderRegistryTest = (input: { Layer.mock(ForgejoCli.ForgejoCli)({ listLogins: () => Effect.succeed([]) }), Layer.mock(VcsDriverRegistry.VcsDriverRegistry)({}), Layer.mock(VcsProcess.VcsProcess)(input.process), + ServerSourceControlHost.layer.pipe( + Layer.provide( + Layer.merge( + Layer.mock(VcsProcess.VcsProcess)(input.process), + ServerSettings.ServerSettingsService.layerTest(), + ), + ), + ), ), ), ); diff --git a/apps/server/src/sourceControl/SourceControlDiscovery.ts b/apps/server/src/sourceControl/SourceControlDiscovery.ts index e178148f131f2865c81ddf36837612e7bfb3b4c1..f56985fefd63900f99e07dad3aa344a8fad4fa1d 100644 --- a/apps/server/src/sourceControl/SourceControlDiscovery.ts +++ b/apps/server/src/sourceControl/SourceControlDiscovery.ts @@ -10,7 +10,7 @@ import * as Option from "effect/Option"; import * as ServerConfig from "../config.ts"; import * as VcsProcess from "../vcs/VcsProcess.ts"; -import { detailFromCause, firstNonEmptyLine } from "./SourceControlProviderDiscovery.ts"; +import { detailFromCause, firstNonEmptyLine } from "@t3tools/source-control-core/server/discovery"; import * as SourceControlProviderRegistry from "./SourceControlProviderRegistry.ts"; interface DiscoveryProbe { diff --git a/apps/server/src/sourceControl/SourceControlProviderRegistry.test.ts b/apps/server/src/sourceControl/SourceControlProviderRegistry.test.ts index 705c38b847b7248174cef630807994ca3f4e07f2..08a7259eb1e1fed88d441caccf736a4a804d784f 100644 --- a/apps/server/src/sourceControl/SourceControlProviderRegistry.test.ts +++ b/apps/server/src/sourceControl/SourceControlProviderRegistry.test.ts @@ -21,6 +21,7 @@ import * as GitHubCredentials from "./GitHubCredentials.ts"; import * as GitLabCli from "./GitLabCli.ts"; import * as ForgejoCli from "./ForgejoCli.ts"; import * as SourceControlProviderRegistry from "./SourceControlProviderRegistry.ts"; +import * as ServerSourceControlHost from "./ServerSourceControlHost.ts"; const TEST_EPOCH = DateTime.makeUnsafe("1970-01-01T00:00:00.000Z"); @@ -96,6 +97,11 @@ function makeRegistry(input: { NodeServices.layer, layerRegistry, layerProcess, + ServerSourceControlHost.layer.pipe( + Layer.provide( + Layer.merge(layerProcess, ServerSettings.ServerSettingsService.layerTest()), + ), + ), Layer.mock(AzureDevOpsCli.AzureDevOpsCli)({}), Layer.mock(BitbucketApi.BitbucketApi)({}), ServerSettings.ServerSettingsService.layerTest(), diff --git a/apps/server/src/sourceControl/SourceControlProviderRegistry.ts b/apps/server/src/sourceControl/SourceControlProviderRegistry.ts index 7a626b13f50ff06109bd56e380bee44c45759f33..309f79b1509fca3f63346f8578b74b16e5f8ded2 100644 --- a/apps/server/src/sourceControl/SourceControlProviderRegistry.ts +++ b/apps/server/src/sourceControl/SourceControlProviderRegistry.ts @@ -16,15 +16,16 @@ import * as BitbucketSourceControlProvider from "./BitbucketSourceControlProvide import * as GitHubSourceControlProvider from "./GitHubSourceControlProvider.ts"; import * as GitLabSourceControlProvider from "./GitLabSourceControlProvider.ts"; import * as ForgejoSourceControlProvider from "./ForgejoSourceControlProvider.ts"; -import * as SourceControlProvider from "./SourceControlProvider.ts"; +import * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import { probeSourceControlProvider, refineUnknownRemoteProvider, type SourceControlProviderDiscoverySpec, -} from "./SourceControlProviderDiscovery.ts"; +} from "@t3tools/source-control-core/server/discovery"; +import * as SourceControlHost from "@t3tools/source-control-core/server/SourceControlHost"; + import * as ServerConfig from "../config.ts"; import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts"; -import * as VcsProcess from "../vcs/VcsProcess.ts"; const PROVIDER_DETECTION_CACHE_CAPACITY = 2_048; const PROVIDER_DETECTION_CACHE_TTL = Duration.seconds(5); @@ -201,7 +202,7 @@ function bindProviderContext( export const makeWithProviders = Effect.fn("makeSourceControlProviderRegistryWithProviders")( function* (registrations: ReadonlyArray) { const config = yield* ServerConfig.ServerConfig; - const process = yield* VcsProcess.VcsProcess; + const { process } = yield* SourceControlHost.SourceControlHost; const vcsRegistry = yield* VcsDriverRegistry.VcsDriverRegistry; const providers = new Map< SourceControlProviderKind, diff --git a/apps/server/src/sourceControl/SourceControlRepositoryService.test.ts b/apps/server/src/sourceControl/SourceControlRepositoryService.test.ts index 3495b2270b3e8c012298e15fa3d892b02382e2ad..8aba02284403b021faff895ecccea956df65f2c7 100644 --- a/apps/server/src/sourceControl/SourceControlRepositoryService.test.ts +++ b/apps/server/src/sourceControl/SourceControlRepositoryService.test.ts @@ -15,7 +15,7 @@ import * as ServerConfig from "../config.ts"; import * as GitVcsDriver from "../vcs/GitVcsDriver.ts"; import * as BitbucketApi from "./BitbucketApi.ts"; import * as BitbucketSourceControlProvider from "./BitbucketSourceControlProvider.ts"; -import type * as SourceControlProvider from "./SourceControlProvider.ts"; +import type * as SourceControlProvider from "@t3tools/source-control-core/server/SourceControlProvider"; import * as SourceControlProviderRegistry from "./SourceControlProviderRegistry.ts"; import * as SourceControlRepositoryService from "./SourceControlRepositoryService.ts"; diff --git a/apps/server/src/sourceControl/githubQuota.test.ts b/apps/server/src/sourceControl/githubQuota.test.ts index e21970cecca72cc87f84cbff28d6eb8d1b216b7f..e9c1fac93eb04be46ceee99bcdb53dc45c477ae9 100644 --- a/apps/server/src/sourceControl/githubQuota.test.ts +++ b/apps/server/src/sourceControl/githubQuota.test.ts @@ -3,7 +3,7 @@ import * as Effect from "effect/Effect"; import * as TestClock from "effect/testing/TestClock"; import * as GitHubQuota from "./githubQuota.ts"; -import { CredentialScope } from "./SourceControlRateLimit.ts"; +import { CredentialScope } from "@t3tools/source-control-core/server/SourceControlRateLimit"; const RESET = Date.parse("2099-08-13T14:00:00Z"); const headers = (remaining: number, resource = "graphql", reset = RESET) => ({ diff --git a/apps/server/src/sourceControl/githubQuota.ts b/apps/server/src/sourceControl/githubQuota.ts index c553535019f452209af1f17c2ccbd28e7c1b8a7b..642c48fddc9a107f869c25ca8b3183a3487530c8 100644 --- a/apps/server/src/sourceControl/githubQuota.ts +++ b/apps/server/src/sourceControl/githubQuota.ts @@ -4,7 +4,7 @@ import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Ref from "effect/Ref"; -import * as SourceControlRateLimit from "./SourceControlRateLimit.ts"; +import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit"; /** The share of each quota a background read leaves for a user's next click. */ const RESERVE_RATIO = 0.1; diff --git a/apps/server/src/ws.ts b/apps/server/src/ws.ts index a035d6971d454e4009818b96613c3caf21c564ae..666805e1d79eec32d230a2219eaea775c9f10795 100644 --- a/apps/server/src/ws.ts +++ b/apps/server/src/ws.ts @@ -235,6 +235,7 @@ import * as GitHubApi from "./sourceControl/GitHubApi.ts"; import * as GitLabCli from "./sourceControl/GitLabCli.ts"; import * as ForgejoCli from "./sourceControl/ForgejoCli.ts"; import * as SourceControlProviderRegistry from "./sourceControl/SourceControlProviderRegistry.ts"; +import * as ServerSourceControlHost from "./sourceControl/ServerSourceControlHost.ts"; import * as GitVcsDriver from "./vcs/GitVcsDriver.ts"; import * as VcsDriverRegistry from "./vcs/VcsDriverRegistry.ts"; import * as VcsProjectConfig from "./vcs/VcsProjectConfig.ts"; @@ -3209,6 +3210,7 @@ export const layer = Layer.unwrap( GitHubApi.layerWithDependencies, GitLabCli.layer, ForgejoCli.layer, + ServerSourceControlHost.layer, ), ), Layer.provideMerge(GitVcsDriver.layer), diff --git a/docs/internals/pull-request-file-revisions.md b/docs/internals/pull-request-file-revisions.md index 3a84b8de665d03cd4ab2bdaf447719cb6290c5d5..22eeb63848eaf6156db5e68cedaccf4d48a51c40 100644 --- a/docs/internals/pull-request-file-revisions.md +++ b/docs/internals/pull-request-file-revisions.md @@ -17,7 +17,7 @@ a project the token cannot see. Below the boundary, in a patch parser or a response decoder, a missing path means this revision does not carry that file. Above it, in -[`ProviderFileRevisions`](../../apps/server/src/pullRequest/PullRequestProvider.ts), a missing path +[`ProviderFileRevisions`](../../packages/source-control-core/src/server/PullRequestProvider.ts), a missing path means the read could not say. A provider's `getFileRevisions` converts on the way up: a path its host looked at and has no version for arrives as the empty string, and absence is kept for what the provider never got to look at. Absence below the boundary does not survive it. diff --git a/package.json b/package.json index 55869fc4b3911ff6b6486767dea7fc9a9230ab7a..471e5361eef280ccc93f4fd3b69f51cd5911f805 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "tc": "vp run -r --concurrency-limit 2 typecheck", "lint": "vp lint --report-unused-disable-directives", "knip": "knip --preprocessor ./scripts/knip-schemas.ts", - "knip:check": "knip --include files,dependencies --no-config-hints && knip --workspace apps/server --workspace apps/desktop --workspace apps/web --workspace packages/client-runtime --workspace packages/contracts --workspace packages/effect-acp --workspace packages/effect-codex-app-server --workspace packages/shared --workspace packages/ssh --workspace packages/tailscale --workspace packages/provider-core --workspace packages/provider-acp --workspace packages/provider-acp-registry --workspace packages/provider-testing --workspace packages/provider-pi --workspace packages/provider-muse --workspace packages/provider-opencode --workspace packages/provider-cursor --workspace packages/provider-grok --exports --preprocessor ./scripts/knip-schemas.ts --no-config-hints", + "knip:check": "knip --include files,dependencies --no-config-hints && knip --workspace apps/server --workspace apps/desktop --workspace apps/web --workspace packages/client-runtime --workspace packages/contracts --workspace packages/effect-acp --workspace packages/effect-codex-app-server --workspace packages/shared --workspace packages/ssh --workspace packages/tailscale --workspace packages/provider-core --workspace packages/provider-acp --workspace packages/provider-acp-registry --workspace packages/provider-testing --workspace packages/provider-pi --workspace packages/provider-muse --workspace packages/provider-opencode --workspace packages/provider-cursor --workspace packages/provider-grok --workspace packages/source-control-core --exports --preprocessor ./scripts/knip-schemas.ts --no-config-hints", "knip:production": "knip --production --preprocessor ./scripts/knip-schemas.ts", "lint:mobile": "node scripts/mobile-native-static-check.ts", "test": "vp run -r test", diff --git a/packages/source-control-core/package.json b/packages/source-control-core/package.json new file mode 100644 index 0000000000000000000000000000000000000000..58742f9f3589bb23360ae5f27628217805467d2a --- /dev/null +++ b/packages/source-control-core/package.json @@ -0,0 +1,48 @@ +{ + "name": "@t3tools/source-control-core", + "private": true, + "type": "module", + "exports": { + "./server/discovery": { + "types": "./src/server/discovery.ts", + "import": "./src/server/discovery.ts" + }, + "./server/mergeMessage": { + "types": "./src/server/mergeMessage.ts", + "import": "./src/server/mergeMessage.ts" + }, + "./server/pullRequestChecks": { + "types": "./src/server/pullRequestChecks.ts", + "import": "./src/server/pullRequestChecks.ts" + }, + "./server/PullRequestProvider": { + "types": "./src/server/PullRequestProvider.ts", + "import": "./src/server/PullRequestProvider.ts" + }, + "./server/SourceControlHost": { + "types": "./src/server/SourceControlHost.ts", + "import": "./src/server/SourceControlHost.ts" + }, + "./server/SourceControlProvider": { + "types": "./src/server/SourceControlProvider.ts", + "import": "./src/server/SourceControlProvider.ts" + }, + "./server/SourceControlRateLimit": { + "types": "./src/server/SourceControlRateLimit.ts", + "import": "./src/server/SourceControlRateLimit.ts" + } + }, + "scripts": { + "typecheck": "tsc --noEmit", + "test": "vp test run --config ../../vite.config.ts --dir ." + }, + "dependencies": { + "@t3tools/contracts": "workspace:*", + "effect": "catalog:" + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "vite-plus": "catalog:" + } +} diff --git a/apps/server/src/pullRequest/PullRequestProvider.ts b/packages/source-control-core/src/server/PullRequestProvider.ts similarity index 100% rename from apps/server/src/pullRequest/PullRequestProvider.ts rename to packages/source-control-core/src/server/PullRequestProvider.ts diff --git a/packages/source-control-core/src/server/SourceControlHost.ts b/packages/source-control-core/src/server/SourceControlHost.ts new file mode 100644 index 0000000000000000000000000000000000000000..d779f86fe0e2019251667ba9b3a9d40781dd6494 --- /dev/null +++ b/packages/source-control-core/src/server/SourceControlHost.ts @@ -0,0 +1,59 @@ +/** + * SourceControlHost — what a source control provider package may ask of the server it runs in. + * + * Providers run inside a T3 server but must not import it. The server provides this one + * service; everything a provider needs from its environment (settings, the process runner) + * goes through it, so a provider package depends only on `@t3tools/source-control-core` and + * its own API and CLI code. HTTP, the filesystem, and paths come from Effect's platform + * services directly. + * + * @module source-control-core/server/SourceControlHost + */ +import type { ServerSettings, ServerSettingsError, VcsError } from "@t3tools/contracts"; +import * as Context from "effect/Context"; +import type * as Effect from "effect/Effect"; +import type * as ChildProcessSpawner from "effect/process/ChildProcessSpawner"; + +/** One CLI invocation. The server bounds concurrency, output, and time for every run. */ +export interface SourceControlProcessInput { + readonly operation: string; + readonly command: string; + readonly args: ReadonlyArray; + readonly cwd: string; + readonly spawnCwd?: string; + readonly stdin?: string; + readonly onStdoutChunk?: (chunk: Uint8Array) => void; + readonly env?: NodeJS.ProcessEnv; + readonly allowNonZeroExit?: boolean; + readonly timeoutMs?: number; + readonly maxOutputBytes?: number; + /** What happens past `maxOutputBytes`: fail the run, or keep the first bytes. */ + readonly outputMode?: "error" | "truncate" | undefined; + readonly appendTruncationMarker?: boolean; +} + +export interface SourceControlProcessOutput { + readonly exitCode: ChildProcessSpawner.ExitCode; + readonly stdout: string; + readonly stderr: string; + readonly stdoutTruncated: boolean; + readonly stderrTruncated: boolean; + /** Present on real process output; optional so narrow test doubles remain lightweight. */ + readonly stdoutInvalidUtf8?: boolean; + readonly stderrInvalidUtf8?: boolean; +} + +export class SourceControlHost extends Context.Service< + SourceControlHost, + { + readonly settings: { + /** Read fresh on each call, so a credential saved in Settings applies without a restart. */ + readonly get: Effect.Effect; + }; + readonly process: { + readonly run: ( + input: SourceControlProcessInput, + ) => Effect.Effect; + }; + } +>()("@t3tools/source-control-core/server/SourceControlHost") {} diff --git a/apps/server/src/sourceControl/SourceControlProvider.test.ts b/packages/source-control-core/src/server/SourceControlProvider.test.ts similarity index 100% rename from apps/server/src/sourceControl/SourceControlProvider.test.ts rename to packages/source-control-core/src/server/SourceControlProvider.test.ts diff --git a/apps/server/src/sourceControl/SourceControlProvider.ts b/packages/source-control-core/src/server/SourceControlProvider.ts similarity index 98% rename from apps/server/src/sourceControl/SourceControlProvider.ts rename to packages/source-control-core/src/server/SourceControlProvider.ts index ec61691fdd424b23066984106f8f63c6ad39bb97..2bcabceb00e349262672352bc65f76d835335fc9 100644 --- a/apps/server/src/sourceControl/SourceControlProvider.ts +++ b/packages/source-control-core/src/server/SourceControlProvider.ts @@ -142,4 +142,4 @@ export class SourceControlProvider extends Context.Service< readonly force?: boolean; }) => Effect.Effect; } ->()("t3/sourceControl/SourceControlProvider") {} +>()("@t3tools/source-control-core/server/SourceControlProvider") {} diff --git a/apps/server/src/sourceControl/SourceControlRateLimit.test.ts b/packages/source-control-core/src/server/SourceControlRateLimit.test.ts similarity index 100% rename from apps/server/src/sourceControl/SourceControlRateLimit.test.ts rename to packages/source-control-core/src/server/SourceControlRateLimit.test.ts diff --git a/apps/server/src/sourceControl/SourceControlRateLimit.ts b/packages/source-control-core/src/server/SourceControlRateLimit.ts similarity index 95% rename from apps/server/src/sourceControl/SourceControlRateLimit.ts rename to packages/source-control-core/src/server/SourceControlRateLimit.ts index dc6242a60eb6b9a53338ca07e899fde8edf965bd..f2ef07dd2529bc9fb453219371cd87cf4fcc7884 100644 --- a/apps/server/src/sourceControl/SourceControlRateLimit.ts +++ b/packages/source-control-core/src/server/SourceControlRateLimit.ts @@ -13,9 +13,12 @@ import { const FALLBACK_COOLDOWN = Duration.seconds(30); const MAX_FALLBACK_COOLDOWN = Duration.minutes(15); -export const CredentialScope = Context.Reference("t3/sourceControl/CredentialScope", { - defaultValue: () => "", -}); +export const CredentialScope = Context.Reference( + "@t3tools/source-control-core/server/SourceControlRateLimit/CredentialScope", + { + defaultValue: () => "", + }, +); interface RateLimitKey { readonly provider: SourceControlProviderKind; @@ -61,7 +64,7 @@ export class SourceControlRateLimit extends Context.Service< ) => Effect.Effect; readonly recordSuccess: (input: RateLimitLease) => Effect.Effect; } ->()("t3/sourceControl/SourceControlRateLimit") {} +>()("@t3tools/source-control-core/server/SourceControlRateLimit") {} function normalizedKey(key: RateLimitKey, scope: string): string { return `${key.provider}\0${key.host.trim().toLowerCase()}\0${scope}`; diff --git a/apps/server/src/sourceControl/SourceControlProviderDiscovery.ts b/packages/source-control-core/src/server/discovery.ts similarity index 95% rename from apps/server/src/sourceControl/SourceControlProviderDiscovery.ts rename to packages/source-control-core/src/server/discovery.ts index 466e662306493b2497c8f58ee6a05b604a5a45fd..70d26b4a963c165d3edd877f08ab485d5f7b0bea 100644 --- a/apps/server/src/sourceControl/SourceControlProviderDiscovery.ts +++ b/packages/source-control-core/src/server/discovery.ts @@ -1,3 +1,8 @@ +/** + * Discovery specs: how each provider reports its CLI or API, and the shared probe that runs them. + * + * @module source-control-core/server/discovery + */ import * as NodeUtil from "node:util"; import type { SourceControlProviderAuth, @@ -9,12 +14,12 @@ import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import type * as SourceControlProvider from "./SourceControlProvider.ts"; -import type * as VcsProcess from "../vcs/VcsProcess.ts"; +import type * as SourceControlHost from "./SourceControlHost.ts"; export interface SourceControlAuthProbeInput { readonly stdout: string; readonly stderr: string; - readonly exitCode: VcsProcess.VcsProcessOutput["exitCode"]; + readonly exitCode: SourceControlHost.SourceControlProcessOutput["exitCode"]; } export interface SourceControlUnknownRemoteRefinementInput { @@ -179,7 +184,7 @@ function isCliRemoteRefinementSpec( function probeCli(input: { readonly spec: SourceControlCliDiscoverySpec; - readonly process: VcsProcess.VcsProcess["Service"]; + readonly process: SourceControlHost.SourceControlHost["Service"]["process"]; readonly cwd: string; }): Effect.Effect { return input.process @@ -223,7 +228,7 @@ function probeCli(input: { export function probeSourceControlProvider(input: { readonly spec: SourceControlProviderDiscoverySpec; - readonly process: VcsProcess.VcsProcess["Service"]; + readonly process: SourceControlHost.SourceControlHost["Service"]["process"]; readonly cwd: string; }): Effect.Effect { if (input.spec.type === "managed-cli") return input.spec.probe(input.cwd); @@ -292,7 +297,7 @@ export function probeSourceControlProvider(input: { export const refineUnknownRemoteProvider = Effect.fn("refineUnknownRemoteProvider")( function* (input: { readonly specs: ReadonlyArray; - readonly process: VcsProcess.VcsProcess["Service"]; + readonly process: SourceControlHost.SourceControlHost["Service"]["process"]; readonly cwd: string; readonly context: SourceControlProvider.SourceControlProviderContext | null; }): Effect.fn.Return { diff --git a/apps/server/src/pullRequest/mergeMessage.test.ts b/packages/source-control-core/src/server/mergeMessage.test.ts similarity index 100% rename from apps/server/src/pullRequest/mergeMessage.test.ts rename to packages/source-control-core/src/server/mergeMessage.test.ts diff --git a/apps/server/src/pullRequest/mergeMessage.ts b/packages/source-control-core/src/server/mergeMessage.ts similarity index 100% rename from apps/server/src/pullRequest/mergeMessage.ts rename to packages/source-control-core/src/server/mergeMessage.ts diff --git a/apps/server/src/pullRequest/pullRequestChecks.test.ts b/packages/source-control-core/src/server/pullRequestChecks.test.ts similarity index 100% rename from apps/server/src/pullRequest/pullRequestChecks.test.ts rename to packages/source-control-core/src/server/pullRequestChecks.test.ts diff --git a/apps/server/src/pullRequest/pullRequestChecks.ts b/packages/source-control-core/src/server/pullRequestChecks.ts similarity index 100% rename from apps/server/src/pullRequest/pullRequestChecks.ts rename to packages/source-control-core/src/server/pullRequestChecks.ts diff --git a/packages/source-control-core/tsconfig.json b/packages/source-control-core/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..374bac55202ddcad695ede1c567ec219a61e9c48 --- /dev/null +++ b/packages/source-control-core/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": ["node"] + }, + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5790c62cc13da7233f2a98f2741d179f0e9e242f..387677cd3d52233f45581c61902da3d2269bfa41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -648,6 +648,9 @@ importers: '@t3tools/provider-pi': specifier: workspace:* version: link:../../packages/provider-pi + '@t3tools/source-control-core': + specifier: workspace:* + version: link:../../packages/source-control-core diff: specifier: 8.0.3 version: 8.0.3 @@ -1510,6 +1513,25 @@ importers: specifier: 1.0.0 version: 1.0.0(@types/node@24.12.4)(@vitest/ui@5.0.1(vitest@5.0.1))(bufferutil@4.1.0)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.1.0(@noble/hashes@1.8.0))(msw@2.12.11(@types/node@24.12.4)(typescript@7.0.2))(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(utf-8-validate@6.0.6)(yaml@2.9.0) + packages/source-control-core: + dependencies: + '@t3tools/contracts': + specifier: workspace:* + version: link:../contracts + effect: + specifier: 4.0.2 + version: 4.0.2(patch_hash=ec61ee307eaec3e17f757e0e6a16296ea4b7a8c3188df0c6ec5e66301fd78688) + devDependencies: + '@effect/vitest': + specifier: 4.0.2 + version: 4.0.2(patch_hash=595b7d26fb635caba9c3d39fcb189bb78a000192f8d3b60ead7174b310d1ade9)(@types/node@24.12.4)(@vitest/ui@5.0.1)(bufferutil@4.1.0)(effect@4.0.2(patch_hash=ec61ee307eaec3e17f757e0e6a16296ea4b7a8c3188df0c6ec5e66301fd78688))(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.1.0(@noble/hashes@1.8.0))(msw@2.12.11(@types/node@24.12.4)(typescript@7.0.2))(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(utf-8-validate@6.0.6)(yaml@2.9.0) + '@types/node': + specifier: 24.12.4 + version: 24.12.4 + vite-plus: + specifier: 1.0.0 + version: 1.0.0(@types/node@24.12.4)(@vitest/ui@5.0.1(vitest@5.0.1))(bufferutil@4.1.0)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.1.0(@noble/hashes@1.8.0))(msw@2.12.11(@types/node@24.12.4)(typescript@7.0.2))(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(utf-8-validate@6.0.6)(yaml@2.9.0) + packages/ssh: dependencies: '@t3tools/contracts': diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index fd8921b67c1265477b7c5db10650179cb6610ca8..f1c903bc8fe1c380cb0adde879771d0bc9974fb9 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -37,6 +37,7 @@ const workspaceFiles = [ "packages/provider-grok/package.json", "packages/provider-muse/package.json", "packages/provider-opencode/package.json", + "packages/source-control-core/package.json", "packages/effect-acp/package.json", "packages/effect-codex-app-server/package.json", "scripts/package.json", -- 2.54.0