From 28f7a52ec8f7c383a69585abeb6843d5f6a16c44 Mon Sep 17 00:00:00 2001 From: Isaac Sanchez-Hawkins <266845420+isanchez404@users.noreply.github.com> Date: Fri, 8 May 2026 08:57:25 -0400 Subject: [PATCH] fix(git): forward status mode to runtimes (#1153) Co-authored-by: Isaac Sanchez --- packages/ui/src/lib/gitApi.test.ts | 50 +++++++++++++++++++++++ packages/ui/src/lib/gitApi.ts | 2 +- packages/vscode/src/bridge-git-runtime.ts | 4 +- packages/vscode/src/gitService.ts | 9 +++- packages/vscode/webview/api/git.ts | 4 +- 5 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 packages/ui/src/lib/gitApi.test.ts diff --git a/packages/ui/src/lib/gitApi.test.ts b/packages/ui/src/lib/gitApi.test.ts new file mode 100644 index 00000000..c901af76 --- /dev/null +++ b/packages/ui/src/lib/gitApi.test.ts @@ -0,0 +1,50 @@ +import { describe, expect, test } from "bun:test" +import type { GitAPI, GitStatus } from "./api/types" +import { getGitStatus } from "./gitApi" + +const status: GitStatus = { + current: "main", + tracking: null, + ahead: 0, + behind: 0, + files: [], + isClean: true, +} + +const withRuntimeGit = async (git: GitAPI, callback: () => Promise) => { + const previousWindowDescriptor = Object.getOwnPropertyDescriptor(globalThis, "window") + Object.defineProperty(globalThis, "window", { + configurable: true, + value: { + __OPENCHAMBER_RUNTIME_APIS__: { git }, + }, + }) + + try { + await callback() + } finally { + if (previousWindowDescriptor) { + Object.defineProperty(globalThis, "window", previousWindowDescriptor) + } else { + delete (globalThis as { window?: Window }).window + } + } +} + +describe("getGitStatus", () => { + test("forwards light-mode options to runtime git APIs", async () => { + let received: { directory: string; options?: { mode?: "light" } } | null = null + const runtimeGit = { + getGitStatus: async (directory: string, options?: { mode?: "light" }) => { + received = { directory, options } + return status + }, + } as Partial as GitAPI + + await withRuntimeGit(runtimeGit, async () => { + await getGitStatus("/repo", { mode: "light" }) + }) + + expect(received).toEqual({ directory: "/repo", options: { mode: "light" } }) + }) +}) diff --git a/packages/ui/src/lib/gitApi.ts b/packages/ui/src/lib/gitApi.ts index d4f9d266..43fd0627 100644 --- a/packages/ui/src/lib/gitApi.ts +++ b/packages/ui/src/lib/gitApi.ts @@ -66,7 +66,7 @@ export async function checkIsGitRepository(directory: string): Promise export async function getGitStatus(directory: string, options?: { mode?: 'light' }): Promise { const runtime = getRuntimeGit(); - if (runtime) return runtime.getGitStatus(directory); + if (runtime) return runtime.getGitStatus(directory, options); return gitHttp.getGitStatus(directory, options); } diff --git a/packages/vscode/src/bridge-git-runtime.ts b/packages/vscode/src/bridge-git-runtime.ts index 63d5889e..adfa1f34 100644 --- a/packages/vscode/src/bridge-git-runtime.ts +++ b/packages/vscode/src/bridge-git-runtime.ts @@ -35,10 +35,10 @@ export async function handleStandardGitBridgeMessage(message: BridgeMessageInput } case 'api:git/status': { - const { directory } = (payload || {}) as { directory?: string }; + const { directory, mode } = (payload || {}) as { directory?: string; mode?: 'light' }; const dirError = requireDirectory(id, type, directory); if (dirError) return dirError; - const status = await gitService.getGitStatus(directory!); + const status = await gitService.getGitStatus(directory!, mode === 'light' ? { mode } : undefined); return { id, type, success: true, data: status }; } diff --git a/packages/vscode/src/gitService.ts b/packages/vscode/src/gitService.ts index ed23ad3a..15f55444 100644 --- a/packages/vscode/src/gitService.ts +++ b/packages/vscode/src/gitService.ts @@ -342,6 +342,10 @@ export interface GitStatusResult { rebaseInProgress?: GitRebaseInProgress | null; } +type GitStatusOptions = { + mode?: 'light'; +}; + /** * Map VS Code git status to our status codes */ @@ -374,7 +378,10 @@ function mapStatus(status: Status): string { /** * Get git status for a directory */ -export async function getGitStatus(directory: string): Promise { +export async function getGitStatus(directory: string, options?: GitStatusOptions): Promise { + // The VS Code Git API path does not compute heavyweight diff stats today, + // but accepts the shared options contract so callers can rely on parity. + void options; const repo = await getRepository(directory); if (!repo) { diff --git a/packages/vscode/webview/api/git.ts b/packages/vscode/webview/api/git.ts index 81084bad..20aba3bb 100644 --- a/packages/vscode/webview/api/git.ts +++ b/packages/vscode/webview/api/git.ts @@ -41,8 +41,8 @@ export const createVSCodeGitAPI = (): GitAPI => ({ return sendBridgeMessage('api:git/check', { directory }); }, - getGitStatus: async (directory: string): Promise => { - return sendBridgeMessage('api:git/status', { directory }); + getGitStatus: async (directory: string, options?: { mode?: 'light' }): Promise => { + return sendBridgeMessage('api:git/status', { directory, mode: options?.mode }); }, getGitDiff: async (directory: string, options: GetGitDiffOptions): Promise => {