Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
"@t3tools/provider-muse": "workspace:*",
"@t3tools/provider-opencode": "workspace:*",
"@t3tools/provider-pi": "workspace:*",
"@t3tools/source-control-azure-devops": "workspace:*",
"@t3tools/source-control-core": "workspace:*",
"@t3tools/source-control-forgejo": "workspace:*",
"diff": "8.0.3",
"effect": "catalog:",
"jose": "catalog:",
"node-pty": "^1.2.0-beta.15",
Expand Down
2 changes: 0 additions & 2 deletions apps/server/scripts/evaluate-thread-titles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import * as SourceControlProviderRegistry from "../src/sourceControl/SourceContr
import * as GitHubApi from "../src/sourceControl/GitHubApi.ts";
import * as GitLabCli from "../src/sourceControl/GitLabCli.ts";
import * as SourceControlBuiltInDrivers from "../src/sourceControl/builtInDrivers.ts";
import * as AzureDevOpsCli from "../src/sourceControl/AzureDevOpsCli.ts";
import * as BitbucketApi from "../src/sourceControl/BitbucketApi.ts";
import * as ServerSettings from "../src/serverSettings.ts";
import * as VcsProcess from "../src/vcs/VcsProcess.ts";
Expand Down Expand Up @@ -155,7 +154,6 @@ await Effect.runPromise(
GitHubApi.layerWithDependencies,
GitLabCli.layer,
SourceControlBuiltInDrivers.layer,
AzureDevOpsCli.layer,
// No saved credentials here; Bitbucket falls back to T3CODE_BITBUCKET_* variables.
BitbucketApi.layer,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { assert, it } from "@effect/vitest";

import * as AzureDevOpsCli from "../sourceControl/AzureDevOpsCli.ts";
import * as AzureDevOpsCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsCli";
import * as BitbucketApi from "../sourceControl/BitbucketApi.ts";
import * as GitHubApi from "../sourceControl/GitHubApi.ts";
import * as SourceControlRateLimit from "@t3tools/source-control-core/server/SourceControlRateLimit";
import * as GitLabCli from "../sourceControl/GitLabCli.ts";
import { azureDevOpsProviderFailure } from "./AzureDevOpsPullRequestProvider.ts";
import { azureDevOpsProviderFailure } from "@t3tools/source-control-azure-devops/server/AzureDevOpsPullRequestProvider";
import { bitbucketProviderFailure } from "./BitbucketPullRequestProvider.ts";
import { gitHubProviderFailure } from "./GitHubPullRequestProvider.ts";
import { gitLabProviderFailure } from "./GitLabPullRequestProvider.ts";
Expand Down
5 changes: 0 additions & 5 deletions apps/server/src/pullRequest/PullRequestProviderRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import type { SourceControlProviderKind } from "@t3tools/contracts";

import * as AzureDevOpsCli from "../sourceControl/AzureDevOpsCli.ts";
import * as BitbucketApi from "../sourceControl/BitbucketApi.ts";
import * as GitHubApi from "../sourceControl/GitHubApi.ts";
import * as GitLabCli from "../sourceControl/GitLabCli.ts";
import * as AzureDevOpsPullRequestCli from "./AzureDevOpsPullRequestCli.ts";
import * as AzureDevOpsPullRequestProvider from "./AzureDevOpsPullRequestProvider.ts";
import * as BitbucketPullRequestApi from "./BitbucketPullRequestApi.ts";
import * as BitbucketPullRequestProvider from "./BitbucketPullRequestProvider.ts";
import * as GitHubPullRequestApi from "./GitHubPullRequestApi.ts";
Expand Down Expand Up @@ -49,7 +46,6 @@ export const make = Effect.gen(function* () {
GitHubPullRequestProvider.make,
GitLabPullRequestProvider.make,
BitbucketPullRequestProvider.make,
AzureDevOpsPullRequestProvider.make,
]);
const drivers = yield* Effect.forEach(BuiltInDrivers.BUILT_IN_SOURCE_CONTROL_DRIVERS, (driver) =>
driver.make.pipe(Effect.map((instance) => instance.pullRequests)),
Expand All @@ -72,5 +68,4 @@ export const layer = Layer.effect(PullRequestProviderRegistry, make).pipe(
Layer.provide(GitLabPullRequestCli.layer.pipe(Layer.provide(GitLabCli.layer))),
Layer.provide(BuiltInDrivers.layer),
Layer.provide(BitbucketPullRequestApi.layer.pipe(Layer.provide(BitbucketApi.layer))),
Layer.provide(AzureDevOpsPullRequestCli.layer.pipe(Layer.provide(AzureDevOpsCli.layer))),
);
2 changes: 0 additions & 2 deletions apps/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import * as ProviderHostLive from "./provider/ProviderHostLive.ts";
import * as AcpRegistrySupport from "@t3tools/provider-acp-registry/server/AcpRegistrySupport";
import * as CheckpointDiffQuery from "./checkpointing/CheckpointDiffQuery.ts";
import * as CheckpointStore from "./checkpointing/CheckpointStore.ts";
import * as AzureDevOpsCli from "./sourceControl/AzureDevOpsCli.ts";
import * as BitbucketApi from "./sourceControl/BitbucketApi.ts";
import * as GitHubApi from "./sourceControl/GitHubApi.ts";
import * as GitLabCli from "./sourceControl/GitLabCli.ts";
Expand Down Expand Up @@ -301,7 +300,6 @@ const layerVcsDriverRegistry = VcsDriverRegistry.layer.pipe(Layer.provide(VcsPro
const layerSourceControlProviderRegistry = SourceControlProviderRegistry.layer.pipe(
Layer.provide(
Layer.mergeAll(
AzureDevOpsCli.layer,
BitbucketApi.layer,
GitHubApi.layerWithDependencies,
GitLabCli.layer,
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/sourceControl/SourceControlDiscovery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import * as ServerConfig from "../config.ts";
import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";
import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts";
import * as VcsProcess from "../vcs/VcsProcess.ts";
import * as AzureDevOpsCli from "./AzureDevOpsCli.ts";
import * as AzureDevOpsCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsCli";
import * as AzureDevOpsPullRequestCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsPullRequestCli";
import * as BitbucketApi from "./BitbucketApi.ts";
import * as GitHubApi from "./GitHubApi.ts";
import * as GitLabCli from "./GitLabCli.ts";
Expand All @@ -39,6 +40,7 @@ const layerSourceControlProviderRegistryTest = (input: {
prefix: "t3-source-control-registry-test-",
}).pipe(Layer.provide(NodeServices.layer)),
Layer.mock(AzureDevOpsCli.AzureDevOpsCli)({}),
Layer.mock(AzureDevOpsPullRequestCli.AzureDevOpsPullRequestCli)({}),
Layer.mock(BitbucketApi.BitbucketApi)(input.bitbucket),
ServerSettings.ServerSettingsService.layerTest(),
Layer.mock(GitHubApi.GitHubApi)({}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import * as ServerConfig from "../config.ts";
import type * as VcsDriver from "../vcs/VcsDriver.ts";
import * as VcsDriverRegistry from "../vcs/VcsDriverRegistry.ts";
import * as VcsProcess from "../vcs/VcsProcess.ts";
import * as AzureDevOpsCli from "./AzureDevOpsCli.ts";
import * as AzureDevOpsCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsCli";
import * as AzureDevOpsPullRequestCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsPullRequestCli";
import * as BitbucketApi from "./BitbucketApi.ts";
import * as GitVcsDriver from "../vcs/GitVcsDriver.ts";
import * as GitHubApi from "./GitHubApi.ts";
Expand Down Expand Up @@ -103,6 +104,7 @@ function makeRegistry(input: {
),
),
Layer.mock(AzureDevOpsCli.AzureDevOpsCli)({}),
Layer.mock(AzureDevOpsPullRequestCli.AzureDevOpsPullRequestCli)({}),
Layer.mock(BitbucketApi.BitbucketApi)({}),
ServerSettings.ServerSettingsService.layerTest(),
Layer.mock(GitHubApi.GitHubApi)({
Expand Down
16 changes: 7 additions & 9 deletions apps/server/src/sourceControl/SourceControlProviderRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
import type { SourceControlProviderKind } from "@t3tools/contracts";
import { detectSourceControlProviderFromRemoteUrl } from "@t3tools/shared/sourceControl";

import * as AzureDevOpsSourceControlProvider from "./AzureDevOpsSourceControlProvider.ts";
import * as BitbucketSourceControlProvider from "./BitbucketSourceControlProvider.ts";
import * as GitHubSourceControlProvider from "./GitHubSourceControlProvider.ts";
import * as GitLabSourceControlProvider from "./GitLabSourceControlProvider.ts";
Expand Down Expand Up @@ -310,7 +309,6 @@ export const make = Effect.gen(function* () {
const gitlab = yield* GitLabSourceControlProvider.make;
const bitbucket = yield* BitbucketSourceControlProvider.make;
const bitbucketDiscovery = yield* BitbucketSourceControlProvider.makeDiscovery;
const azureDevOps = yield* AzureDevOpsSourceControlProvider.make;
const drivers = yield* Effect.forEach(BuiltInDrivers.BUILT_IN_SOURCE_CONTROL_DRIVERS, (driver) =>
driver.make.pipe(
Effect.map((instance): SourceControlProviderRegistration => ({
Expand All @@ -320,7 +318,9 @@ export const make = Effect.gen(function* () {
})),
),
);
return yield* makeWithProviders([
// Discovery lists hosts in this order, so it is kept while hosts move into packages.
const order = ["github", "gitlab", "azure-devops", "bitbucket", "forgejo"];
const registrations: ReadonlyArray<SourceControlProviderRegistration> = [
{
kind: "github",
provider: github,
Expand All @@ -331,18 +331,16 @@ export const make = Effect.gen(function* () {
provider: gitlab,
discovery: GitLabSourceControlProvider.discovery,
},
{
kind: "azure-devops",
provider: azureDevOps,
discovery: AzureDevOpsSourceControlProvider.discovery,
},
{
kind: "bitbucket",
provider: bitbucket,
discovery: bitbucketDiscovery,
},
...drivers,
]);
];
return yield* makeWithProviders(
registrations.toSorted((left, right) => order.indexOf(left.kind) - order.indexOf(right.kind)),
);
});

export const layer = Layer.effect(SourceControlProviderRegistry, make);
20 changes: 17 additions & 3 deletions apps/server/src/sourceControl/builtInDrivers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,28 @@
*
* @module sourceControl/builtInDrivers
*/
import * as AzureDevOpsCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsCli";
import * as AzureDevOpsPullRequestCli from "@t3tools/source-control-azure-devops/server/AzureDevOpsPullRequestCli";
import * as AzureDevOpsDriver from "@t3tools/source-control-azure-devops/server/driver";
import * as ForgejoCli from "@t3tools/source-control-forgejo/server/ForgejoCli";
import * as ForgejoDriver from "@t3tools/source-control-forgejo/server/driver";
import type { SourceControlDriver } from "@t3tools/source-control-core/server/driver";
import * as Layer from "effect/Layer";

import * as ServerSourceControlHost from "./ServerSourceControlHost.ts";

/** Ordered as the hosts appear in discovery, after the ones still built in the server. */
export const BUILT_IN_SOURCE_CONTROL_DRIVERS = [ForgejoDriver.driver] as const;
const drivers = [AzureDevOpsDriver.driver, ForgejoDriver.driver];

/** Every service a built-in driver's `make` needs; the server's layers must provide them all. */
export type BuiltInSourceControlDriversEnv =
(typeof drivers)[number] extends SourceControlDriver<infer R> ? R : never;

export const BUILT_IN_SOURCE_CONTROL_DRIVERS: ReadonlyArray<
SourceControlDriver<BuiltInSourceControlDriversEnv>
> = drivers;

/** The services the built-in drivers' packages own, plus the host port they all run against. */
export const layer = ForgejoCli.layer.pipe(Layer.provideMerge(ServerSourceControlHost.layer));
export const layer = Layer.mergeAll(
AzureDevOpsPullRequestCli.layer.pipe(Layer.provideMerge(AzureDevOpsCli.layer)),
ForgejoCli.layer,
).pipe(Layer.provideMerge(ServerSourceControlHost.layer));
2 changes: 0 additions & 2 deletions apps/server/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@ import * as SqlClient from "effect/sql/SqlClient";
import * as PullRequestSyncReactor from "./orchestration-v2/PullRequestSyncReactor.ts";
import * as SourceControlDiscovery from "./sourceControl/SourceControlDiscovery.ts";
import * as SourceControlRepositoryService from "./sourceControl/SourceControlRepositoryService.ts";
import * as AzureDevOpsCli from "./sourceControl/AzureDevOpsCli.ts";
import * as BitbucketApi from "./sourceControl/BitbucketApi.ts";
import * as GitHubApi from "./sourceControl/GitHubApi.ts";
import * as GitLabCli from "./sourceControl/GitLabCli.ts";
Expand Down Expand Up @@ -3204,7 +3203,6 @@ export const layer = Layer.unwrap(
SourceControlProviderRegistry.layer.pipe(
Layer.provide(
Layer.mergeAll(
AzureDevOpsCli.layer,
BitbucketApi.layer,
GitHubApi.layerWithDependencies,
GitLabCli.layer,
Expand Down
2 changes: 1 addition & 1 deletion docs/internals/pull-request-file-revisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ the provider never got to look at. Absence below the boundary does not survive i

What "never got to look at" is belongs to the host, and the contract cannot know any of them:

- [Azure DevOps](../../apps/server/src/pullRequest/AzureDevOpsPullRequestProvider.ts) reads every
- [Azure DevOps](../../packages/source-control-azure-devops/src/server/AzureDevOpsPullRequestProvider.ts) reads every
version off one iteration listing, so a change too long to follow to its end leaves the paths
past that point out.
- [Bitbucket](../../apps/server/src/pullRequest/BitbucketPullRequestApi.ts) reads them off the
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 --workspace packages/source-control-core --workspace packages/source-control-forgejo --workspace packages/source-control-testing --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 --workspace packages/source-control-azure-devops --workspace packages/source-control-forgejo --workspace packages/source-control-testing --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",
Expand Down
57 changes: 57 additions & 0 deletions packages/source-control-azure-devops/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@t3tools/source-control-azure-devops",
"private": true,
"type": "module",
"exports": {
"./server/AzureDevOpsCli": {
"types": "./src/server/AzureDevOpsCli.ts",
"import": "./src/server/AzureDevOpsCli.ts"
},
"./server/azureDevOpsDiff": {
"types": "./src/server/azureDevOpsDiff.ts",
"import": "./src/server/azureDevOpsDiff.ts"
},
"./server/AzureDevOpsPullRequestCli": {
"types": "./src/server/AzureDevOpsPullRequestCli.ts",
"import": "./src/server/AzureDevOpsPullRequestCli.ts"
},
"./server/azureDevOpsPullRequestJson": {
"types": "./src/server/azureDevOpsPullRequestJson.ts",
"import": "./src/server/azureDevOpsPullRequestJson.ts"
},
"./server/AzureDevOpsPullRequestProvider": {
"types": "./src/server/AzureDevOpsPullRequestProvider.ts",
"import": "./src/server/AzureDevOpsPullRequestProvider.ts"
},
"./server/azureDevOpsPullRequests": {
"types": "./src/server/azureDevOpsPullRequests.ts",
"import": "./src/server/azureDevOpsPullRequests.ts"
},
"./server/AzureDevOpsSourceControlProvider": {
"types": "./src/server/AzureDevOpsSourceControlProvider.ts",
"import": "./src/server/AzureDevOpsSourceControlProvider.ts"
},
"./server/driver": {
"types": "./src/server/driver.ts",
"import": "./src/server/driver.ts"
}
},
"scripts": {
"typecheck": "tsc --noEmit",
"test": "vp test run --config ../../vite.config.ts --dir ."
},
"dependencies": {
"@t3tools/contracts": "workspace:*",
"@t3tools/shared": "workspace:*",
"@t3tools/source-control-core": "workspace:*",
"diff": "8.0.3",
"effect": "catalog:"
},
"devDependencies": {
"@effect/platform-node": "catalog:",
"@effect/vitest": "catalog:",
"@t3tools/source-control-testing": "workspace:*",
"@types/node": "catalog:",
"vite-plus": "catalog:"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,22 @@ import * as PlatformError from "effect/PlatformError";
import { ChildProcessSpawner } from "effect/process";
import { VcsProcessExitError, VcsProcessSpawnError } from "@t3tools/contracts";

import * as VcsProcess from "../vcs/VcsProcess.ts";
import type * as SourceControlHost from "@t3tools/source-control-core/server/SourceControlHost";
import * as TestSourceControlHost from "@t3tools/source-control-testing/TestSourceControlHost";
import * as AzureDevOpsCli from "./AzureDevOpsCli.ts";

const processOutput = (stdout: string): VcsProcess.VcsProcessOutput => ({
const processOutput = (stdout: string): SourceControlHost.SourceControlProcessOutput => ({
exitCode: ChildProcessSpawner.ExitCode(0),
stdout,
stderr: "",
stdoutTruncated: false,
stderrTruncated: false,
});

const mockRun = vi.fn<VcsProcess.VcsProcess["Service"]["run"]>();
const mockRun = vi.fn<SourceControlHost.SourceControlHost["Service"]["process"]["run"]>();

const layerSupport = Layer.mergeAll(
Layer.mock(VcsProcess.VcsProcess)({
run: mockRun,
}),
TestSourceControlHost.layer({ process: { run: mockRun } }),
NodeServices.layer,
);
const layer = Layer.mergeAll(AzureDevOpsCli.layer.pipe(Layer.provide(layerSupport)), layerSupport);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
type VcsError,
} from "@t3tools/contracts";

import * as VcsProcess from "../vcs/VcsProcess.ts";
import * as SourceControlHost from "@t3tools/source-control-core/server/SourceControlHost";
import {
decodeAzureDevOpsPullRequestJson,
decodeAzureDevOpsPullRequestListJson,
Expand Down Expand Up @@ -217,7 +217,7 @@ export class AzureDevOpsCli extends Context.Service<
readonly args: ReadonlyArray<string>;
readonly timeoutMs?: number;
readonly maxOutputBytes?: number;
}) => Effect.Effect<VcsProcess.VcsProcessOutput, AzureDevOpsCliError>;
}) => Effect.Effect<SourceControlHost.SourceControlProcessOutput, AzureDevOpsCliError>;

readonly listPullRequests: (input: {
readonly cwd: string;
Expand Down Expand Up @@ -263,7 +263,7 @@ export class AzureDevOpsCli extends Context.Service<
readonly remoteName?: string;
}) => Effect.Effect<void, AzureDevOpsCliError>;
}
>()("t3/sourceControl/AzureDevOpsCli") {}
>()("@t3tools/source-control-azure-devops/server/AzureDevOpsCli") {}

function normalizeChangeRequestId(reference: string): string {
const trimmed = reference.trim().replace(/^#/, "");
Expand Down Expand Up @@ -352,7 +352,7 @@ function decodeAzureDevOpsJson<S extends Schema.Top>(

/** @public Service construction is part of the canonical Effect module API. */
export const make = Effect.gen(function* () {
const process = yield* VcsProcess.VcsProcess;
const { process } = yield* SourceControlHost.SourceControlHost;

const execute: AzureDevOpsCli["Service"]["execute"] = (input) =>
process
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import { ChildProcessSpawner } from "effect/process";

import * as AzureDevOpsCli from "../sourceControl/AzureDevOpsCli.ts";
import * as AzureDevOpsCli from "./AzureDevOpsCli.ts";
import * as AzureDevOpsPullRequestCli from "./AzureDevOpsPullRequestCli.ts";
import * as AzureDevOpsPullRequestProvider from "./AzureDevOpsPullRequestProvider.ts";

Expand Down
Loading
Loading