feat(vcs): expose repository branch metadata

This commit is contained in:
Brendan Allan 2026-07-21 19:02:18 +08:00
commit 305466e5ef
No known key found for this signature in database
GPG key ID: 41E835AEA046A32E
8 changed files with 48 additions and 3 deletions

View file

@ -2,7 +2,7 @@ export * as Vcs from "./vcs"
import { Context, Effect, Layer } from "effect"
import { FileDiff } from "@opencode-ai/schema/file-diff"
import { FileStatus, Mode } from "@opencode-ai/schema/vcs"
import { FileStatus, Info, Mode } from "@opencode-ai/schema/vcs"
import { makeLocationNode } from "@opencode-ai/util/effect/app-node"
import { FSUtil } from "@opencode-ai/util/fs-util"
import { Location } from "./location"
@ -10,13 +10,14 @@ import { AppProcess } from "@opencode-ai/util/process"
import { VcsGit } from "./vcs/git"
import { VcsHg } from "./vcs/hg"
export { FileStatus, Mode }
export { FileStatus, Info, Mode }
export interface DiffOptions {
readonly context?: number
}
export interface Interface {
readonly info: () => Effect.Effect<Info>
readonly status: () => Effect.Effect<FileStatus[]>
readonly diff: (mode: Mode, options?: DiffOptions) => Effect.Effect<FileDiff.Info[]>
}
@ -40,6 +41,10 @@ const layer = Layer.effect(
const location = yield* Location.Service
const impl = adapter(proc, fs, location)
return Service.of({
info: Effect.fn("Vcs.info")(function* () {
if (!impl) return {}
return yield* impl.info()
}),
status: Effect.fn("Vcs.status")(function* () {
if (!impl) return []
return yield* impl.status()

View file

@ -20,6 +20,12 @@ export function make(proc: AppProcess.Interface, input: { directory: string; wor
const ctx: Ctx = { git: makeGit(proc), directory: input.directory, worktree: input.worktree }
return {
info: Effect.fn("VcsGit.info")(function* () {
const [branch, root] = yield* Effect.all([ctx.git.branch(ctx.directory), ctx.git.defaultBranch(ctx.directory)], {
concurrency: 2,
})
return { branch, defaultBranch: root?.name }
}),
status: Effect.fn("VcsGit.status")(function* () {
const git = ctx.git
const ref = (yield* git.hasHead(ctx.directory)) ? "HEAD" : undefined

View file

@ -73,6 +73,9 @@ export function make(
})
return {
info: Effect.fn("VcsHg.info")(function* () {
return { branch: yield* hg.branch(), defaultBranch: "default" }
}),
status: Effect.fn("VcsHg.status")(function* () {
const [items, batch] = yield* Effect.all(
// Zero-context patches are enough to count changed lines.