232 lines · 6.5 KB · TypeScript
RawDownload
import * as Schema from "effect/Schema";import { TrimmedNonEmptyString } from "./baseSchemas.ts"; export const VcsDriverKind = Schema.Literals(["git", "jj", "unknown"]);export type VcsDriverKind = typeof VcsDriverKind.Type; export const VcsFreshnessSource = Schema.Literals([  "live-local",  "cached-local",  "cached-remote",  "explicit-remote",]);export type VcsFreshnessSource = typeof VcsFreshnessSource.Type; export const VcsFreshness = Schema.Struct({  source: VcsFreshnessSource,  observedAt: Schema.DateTimeUtc,  expiresAt: Schema.Option(Schema.DateTimeUtc),});export type VcsFreshness = typeof VcsFreshness.Type; export const VcsDriverCapabilities = Schema.Struct({  kind: VcsDriverKind,  supportsWorktrees: Schema.Boolean,  supportsBookmarks: Schema.Boolean,  supportsAtomicSnapshot: Schema.Boolean,  supportsPushDefaultRemote: Schema.Boolean,  ignoreClassifier: Schema.Literals(["native", "git-compatible-fallback"]),});export type VcsDriverCapabilities = typeof VcsDriverCapabilities.Type; export const VcsRepositoryIdentity = Schema.Struct({  kind: VcsDriverKind,  rootPath: TrimmedNonEmptyString,  metadataPath: Schema.NullOr(TrimmedNonEmptyString),  freshness: VcsFreshness,});export type VcsRepositoryIdentity = typeof VcsRepositoryIdentity.Type; export const VcsListWorkspaceFilesResult = Schema.Struct({  paths: Schema.Array(TrimmedNonEmptyString),  truncated: Schema.Boolean,  freshness: VcsFreshness,});export type VcsListWorkspaceFilesResult = typeof VcsListWorkspaceFilesResult.Type; export const VcsRemote = Schema.Struct({  name: TrimmedNonEmptyString,  url: TrimmedNonEmptyString,  pushUrl: Schema.Option(TrimmedNonEmptyString),  isPrimary: Schema.Boolean,});export type VcsRemote = typeof VcsRemote.Type; export const VcsListRemotesResult = Schema.Struct({  remotes: Schema.Array(VcsRemote),  freshness: VcsFreshness,});export type VcsListRemotesResult = typeof VcsListRemotesResult.Type; export interface VcsProcessErrorContext {  readonly operation: string;  readonly command: string;  readonly cwd: string;} export interface VcsProcessSpawnFailure {  readonly cause: unknown;} export interface VcsProcessStdinFailure {  readonly cause: unknown;} export interface VcsProcessReadFailure {  readonly stream: "stdout" | "stderr" | "exitCode";  readonly cause: unknown;} export interface VcsProcessOutputLimitFailure {  readonly stream: "stdout" | "stderr";  readonly maxBytes: number;} export interface VcsProcessTimeoutFailure {  readonly timeoutMs: number;} export class VcsProcessSpawnError extends Schema.TaggedErrorClass<VcsProcessSpawnError>()(  "VcsProcessSpawnError",  {    operation: Schema.String,    command: Schema.String,    cwd: Schema.String,    cause: Schema.Defect,  },) {  override get message(): string {    return `VCS process failed to spawn in ${this.operation}: ${this.command} (${this.cwd})`;  }   static fromProcessSpawnError(context: VcsProcessErrorContext, error: VcsProcessSpawnFailure) {    return new VcsProcessSpawnError({      ...context,      cause: error.cause,    });  }} export class VcsProcessExitError extends Schema.TaggedErrorClass<VcsProcessExitError>()(  "VcsProcessExitError",  {    operation: Schema.String,    command: Schema.String,    cwd: Schema.String,    exitCode: Schema.Number,    detail: Schema.String,  },) {  override get message(): string {    return `VCS process failed in ${this.operation}: ${this.command} (${this.cwd}) exited with ${this.exitCode} - ${this.detail}`;  }} export class VcsProcessTimeoutError extends Schema.TaggedErrorClass<VcsProcessTimeoutError>()(  "VcsProcessTimeoutError",  {    operation: Schema.String,    command: Schema.String,    cwd: Schema.String,    timeoutMs: Schema.Number,  },) {  override get message(): string {    return `VCS process timed out in ${this.operation}: ${this.command} (${this.cwd}) after ${this.timeoutMs}ms`;  }   static fromProcessTimeoutError(context: VcsProcessErrorContext, error: VcsProcessTimeoutFailure) {    return new VcsProcessTimeoutError({      ...context,      timeoutMs: error.timeoutMs,    });  }} export class VcsOutputDecodeError extends Schema.TaggedErrorClass<VcsOutputDecodeError>()(  "VcsOutputDecodeError",  {    operation: Schema.String,    command: Schema.String,    cwd: Schema.String,    detail: Schema.String,    cause: Schema.optional(Schema.Defect),  },) {  override get message(): string {    return `VCS output decode failed in ${this.operation}: ${this.command} (${this.cwd}) - ${this.detail}`;  }   static fromProcessStdinError(context: VcsProcessErrorContext, error: VcsProcessStdinFailure) {    return new VcsOutputDecodeError({      ...context,      detail: "failed to write process stdin",      cause: error.cause,    });  }   static fromProcessReadError(context: VcsProcessErrorContext, error: VcsProcessReadFailure) {    return new VcsOutputDecodeError({      ...context,      detail:        error.stream === "exitCode"          ? "failed to read process exit code"          : `failed to read process ${error.stream}`,      cause: error.cause,    });  }   static fromProcessOutputLimitError(    context: VcsProcessErrorContext,    error: VcsProcessOutputLimitFailure,  ) {    return new VcsOutputDecodeError({      ...context,      detail: `process ${error.stream} exceeded ${error.maxBytes} bytes`,    });  }   static missingExitCode(context: VcsProcessErrorContext) {    return new VcsOutputDecodeError({      ...context,      detail: "process completed without an exit code",    });  }} export class VcsRepositoryDetectionError extends Schema.TaggedErrorClass<VcsRepositoryDetectionError>()(  "VcsRepositoryDetectionError",  {    operation: Schema.String,    cwd: Schema.String,    detail: Schema.String,    cause: Schema.optional(Schema.Defect),  },) {  override get message(): string {    return `VCS repository detection failed in ${this.operation}: ${this.cwd} - ${this.detail}`;  }} export class VcsUnsupportedOperationError extends Schema.TaggedErrorClass<VcsUnsupportedOperationError>()(  "VcsUnsupportedOperationError",  {    operation: Schema.String,    kind: VcsDriverKind,    detail: Schema.String,  },) {  override get message(): string {    return `VCS operation is unsupported for ${this.kind} in ${this.operation}: ${this.detail}`;  }} export const VcsError = Schema.Union([  VcsProcessSpawnError,  VcsProcessExitError,  VcsProcessTimeoutError,  VcsOutputDecodeError,  VcsRepositoryDetectionError,  VcsUnsupportedOperationError,]);export type VcsError = typeof VcsError.Type;