313 lines · 8.2 KB · TypeScript
RawDownload
/** * GitCore - Effect service contract for low-level Git operations. * * Wraps core repository primitives used by higher-level orchestration * services and WebSocket routes. * * @module GitCore */import { Context } from "effect";import type { Effect } from "effect";import type {  GitCheckoutInput,  GitCheckoutResult,  GitCreateBranchInput,  GitCreateBranchResult,  GitCreateWorktreeInput,  GitCreateWorktreeResult,  GitInitInput,  GitListBranchesInput,  GitListBranchesResult,  GitPullResult,  GitRemoveWorktreeInput,  GitStatusInput,  GitStatusResult,} from "@t3tools/contracts"; import type { GitCommandError } from "@t3tools/contracts"; export interface ExecuteGitInput {  readonly operation: string;  readonly cwd: string;  readonly args: ReadonlyArray<string>;  readonly stdin?: string;  readonly env?: NodeJS.ProcessEnv;  readonly allowNonZeroExit?: boolean;  readonly timeoutMs?: number;  readonly maxOutputBytes?: number;  readonly truncateOutputAtMaxBytes?: boolean;  readonly progress?: ExecuteGitProgress;} export interface ExecuteGitResult {  readonly code: number;  readonly stdout: string;  readonly stderr: string;  readonly stdoutTruncated: boolean;  readonly stderrTruncated: boolean;} export interface GitStatusDetails extends Omit<GitStatusResult, "pr"> {  upstreamRef: string | null;} export interface GitPreparedCommitContext {  stagedSummary: string;  stagedPatch: string;} export interface ExecuteGitProgress {  readonly onStdoutLine?: (line: string) => Effect.Effect<void, never>;  readonly onStderrLine?: (line: string) => Effect.Effect<void, never>;  readonly onHookStarted?: (hookName: string) => Effect.Effect<void, never>;  readonly onHookFinished?: (input: {    hookName: string;    exitCode: number | null;    durationMs: number | null;  }) => Effect.Effect<void, never>;} export interface GitCommitProgress {  readonly onOutputLine?: (input: {    stream: "stdout" | "stderr";    text: string;  }) => Effect.Effect<void, never>;  readonly onHookStarted?: (hookName: string) => Effect.Effect<void, never>;  readonly onHookFinished?: (input: {    hookName: string;    exitCode: number | null;    durationMs: number | null;  }) => Effect.Effect<void, never>;} export interface GitCommitOptions {  readonly timeoutMs?: number;  readonly progress?: GitCommitProgress;} export interface GitPushResult {  status: "pushed" | "skipped_up_to_date";  branch: string;  upstreamBranch?: string | undefined;  setUpstream?: boolean | undefined;} export interface GitRangeContext {  commitSummary: string;  diffSummary: string;  diffPatch: string;} export interface GitListWorkspaceFilesResult {  readonly paths: ReadonlyArray<string>;  readonly truncated: boolean;} export interface GitRenameBranchInput {  cwd: string;  oldBranch: string;  newBranch: string;} export interface GitRenameBranchResult {  branch: string;} export interface GitFetchPullRequestBranchInput {  cwd: string;  prNumber: number;  branch: string;} export interface GitEnsureRemoteInput {  cwd: string;  preferredName: string;  url: string;} export interface GitFetchRemoteBranchInput {  cwd: string;  remoteName: string;  remoteBranch: string;  localBranch: string;} export interface GitSetBranchUpstreamInput {  cwd: string;  branch: string;  remoteName: string;  remoteBranch: string;} /** * GitCoreShape - Service API for low-level Git repository interactions. */export interface GitCoreShape {  /**   * Execute a raw Git command.   */  readonly execute: (input: ExecuteGitInput) => Effect.Effect<ExecuteGitResult, GitCommandError>;   /**   * Read Git status for a repository.   */  readonly status: (input: GitStatusInput) => Effect.Effect<GitStatusResult, GitCommandError>;   /**   * Read detailed working tree / branch status for a repository.   */  readonly statusDetails: (cwd: string) => Effect.Effect<GitStatusDetails, GitCommandError>;   /**   * Read detailed working tree / branch status without refreshing remote tracking refs.   */  readonly statusDetailsLocal: (cwd: string) => Effect.Effect<GitStatusDetails, GitCommandError>;   /**   * Build staged change context for commit generation.   */  readonly prepareCommitContext: (    cwd: string,    filePaths?: readonly string[],  ) => Effect.Effect<GitPreparedCommitContext | null, GitCommandError>;   /**   * Create a commit with provided subject/body.   */  readonly commit: (    cwd: string,    subject: string,    body: string,    options?: GitCommitOptions,  ) => Effect.Effect<{ commitSha: string }, GitCommandError>;   /**   * Push current branch, setting upstream if needed.   */  readonly pushCurrentBranch: (    cwd: string,    fallbackBranch: string | null,  ) => Effect.Effect<GitPushResult, GitCommandError>;   /**   * Collect commit/diff context between base branch and current HEAD.   */  readonly readRangeContext: (    cwd: string,    baseBranch: string,  ) => Effect.Effect<GitRangeContext, GitCommandError>;   /**   * Read a Git config value from the local repository.   */  readonly readConfigValue: (    cwd: string,    key: string,  ) => Effect.Effect<string | null, GitCommandError>;   /**   * Determine whether the provided cwd is inside a git work tree.   */  readonly isInsideWorkTree: (cwd: string) => Effect.Effect<boolean, GitCommandError>;   /**   * List tracked and untracked workspace file paths relative to cwd.   */  readonly listWorkspaceFiles: (    cwd: string,  ) => Effect.Effect<GitListWorkspaceFilesResult, GitCommandError>;   /**   * Remove gitignored paths from a relative path list.   */  readonly filterIgnoredPaths: (    cwd: string,    relativePaths: ReadonlyArray<string>,  ) => Effect.Effect<ReadonlyArray<string>, GitCommandError>;   /**   * List local + remote branches and branch metadata.   */  readonly listBranches: (    input: GitListBranchesInput,  ) => Effect.Effect<GitListBranchesResult, GitCommandError>;   /**   * Pull current branch from upstream using fast-forward only.   */  readonly pullCurrentBranch: (cwd: string) => Effect.Effect<GitPullResult, GitCommandError>;   /**   * Create a worktree and branch from a base branch.   */  readonly createWorktree: (    input: GitCreateWorktreeInput,  ) => Effect.Effect<GitCreateWorktreeResult, GitCommandError>;   /**   * Materialize a GitHub pull request head as a local branch without switching checkout.   */  readonly fetchPullRequestBranch: (    input: GitFetchPullRequestBranchInput,  ) => Effect.Effect<void, GitCommandError>;   /**   * Ensure a named remote exists for the provided URL, returning the reused or created remote name.   */  readonly ensureRemote: (input: GitEnsureRemoteInput) => Effect.Effect<string, GitCommandError>;   /**   * Fetch a remote branch into a local branch without checkout.   */  readonly fetchRemoteBranch: (    input: GitFetchRemoteBranchInput,  ) => Effect.Effect<void, GitCommandError>;   /**   * Set the upstream tracking branch for a local branch.   */  readonly setBranchUpstream: (    input: GitSetBranchUpstreamInput,  ) => Effect.Effect<void, GitCommandError>;   /**   * Remove an existing worktree.   */  readonly removeWorktree: (input: GitRemoveWorktreeInput) => Effect.Effect<void, GitCommandError>;   /**   * Rename an existing local branch.   */  readonly renameBranch: (    input: GitRenameBranchInput,  ) => Effect.Effect<GitRenameBranchResult, GitCommandError>;   /**   * Create a local branch.   */  readonly createBranch: (    input: GitCreateBranchInput,  ) => Effect.Effect<GitCreateBranchResult, GitCommandError>;   /**   * Checkout an existing branch and refresh its upstream metadata in background.   */  readonly checkoutBranch: (    input: GitCheckoutInput,  ) => Effect.Effect<GitCheckoutResult, GitCommandError>;   /**   * Initialize a repository in the provided directory.   */  readonly initRepo: (input: GitInitInput) => Effect.Effect<void, GitCommandError>;   /**   * List local branch names (short format).   */  readonly listLocalBranchNames: (cwd: string) => Effect.Effect<string[], GitCommandError>;} /** * GitCore - Service tag for low-level Git repository operations. */export class GitCore extends Context.Service<GitCore, GitCoreShape>()("t3/git/Services/GitCore") {}