Skip to content

ranglang/git-web-rpc

Repository files navigation

🔀 git-web-rpc

Full Git in the browser. Zero WASM. One HTTP endpoint.

一个让浏览器拥有完整 Git 能力的 RPC 框架 —— 无需 WASM,一个 HTTP 端点搞定一切。

TypeScript License: MIT PRs Welcome isomorphic-git

English · 中文


Why

Building a browser IDE? A Git GUI? An AI coding sandbox with OpenClaw? Running inside WebContainers?

You need Git — but git doesn't run in the browser. WASM ports are heavy and incomplete.

git-web-rpc gives your browser a git object that looks and feels like the real thing:

const git = createGitProxy({ endpoint: '/api/git' })

await git.clone({ dir: '/repo', url: 'https://github.com/user/repo' })
await git.add({ dir: '/repo', filepath: 'README.md' })
await git.commit({ dir: '/repo', message: 'from the browser', author: { name: 'Dev', email: 'dev@example.com' } })

Under the hood, every call is transparently proxied via ES Proxy to a server running isomorphic-git. Your UI code stays clean. The transport is invisible.

为什么

想在浏览器里做 IDE?做 Git GUI?用 OpenClaw 做 AI 编程沙箱?在 WebContainers 里运行?

你需要 Git —— 但 git 无法在浏览器中运行。WASM 方案又重又不完整。

git-web-rpc 给浏览器提供一个 git 对象,用起来和真正的 Git API 一模一样。底层通过 ES Proxy 将每次调用透明转发到服务端的 isomorphic-git。UI 代码保持干净,传输层完全透明。


Features / 功能特性

English 中文
🪄 ES Proxy magic — calls look local, execute remote ES Proxy 魔法 — 调用看起来是本地的,实际远程执行
🔒 End-to-end type safety — shared types, zero any 端到端类型安全 — 共享类型定义,零 any
⚛️ React hooksuseStatusMatrix, useGitCommit, etc. React HooksuseStatusMatrixuseGitCommit
📡 Real-time SSE — live progress + file-watcher notifications 实时 SSE — 实时进度 + 文件变更通知
🧊 Sandbox isolation — per-session memfs, multi-user safe 沙箱隔离 — 每会话独立 memfs,多用户安全
🔌 Pluggable adapters — Node.js, Express, Next.js App Router 可插拔适配器 — Node.js、Express、Next.js
🖥️ CLIgit-rpc-serve starts a server in one command CLI — 一条命令启动服务
📂 File watching — chokidar pushes status changes via SSE 文件监听 — chokidar 自动推送状态变更

How It Works / 工作原理

Browser                                          Server
┌─────────────────────┐                ┌──────────────────────────┐
│  React Components   │                │  HTTP Router             │
│  useStatusMatrix()  │                │    ↓                     │
│  useGitCommit()     │                │  Git Router (whitelist)  │
│        ↓            │   HTTP POST    │    ↓                     │
│  ES Proxy Client    │ ─────────────► │  isomorphic-git          │
│  git.commit(args)   │                │  { fs: memfs, ...args }  │
│        ↓            │   ◄─────────── │    ↓                     │
│  { ok, data }       │   JSON resp    │  { ok, data }            │
│                     │                │                          │
│  EventSource  ◄─────│── SSE ────────│── StatusNotifier         │
│  (live updates)     │                │   + FileWatcher          │
└─────────────────────┘                └──────────────────────────┘

The client creates an ES Proxy object. Any property access (e.g. git.status) returns an async function that serializes the call as { method, args } and sends it via HTTP POST. The server validates the method against a whitelist, injects fs/http dependencies, and calls isomorphic-git. Network operations (clone/push/pull) stream progress back over SSE.

客户端创建一个 ES Proxy 对象。任何属性访问(如 git.status)都返回一个异步函数,将调用序列化为 { method, args } 并通过 HTTP POST 发送。服务端校验白名单、注入 fs/http 依赖后调用 isomorphic-git。网络操作(clone/push/pull)通过 SSE 实时推送进度。


Getting Started / 快速开始

Prerequisites / 前置条件

  • Node.js >= 18
  • npm or pnpm

Install / 安装

# Install root dependencies / 安装根目录依赖
npm install

# Install frontend dependencies / 安装前端依赖
cd web && npm install

Run / 运行

# Start both backend (port 3001) and frontend (port 5173)
# 同时启动后端 (3001) 和前端 (5173)
npx task dev

Or start them separately / 或分别启动:

npx ts-node packages/server/httpAdapter.ts   # backend / 后端
cd web && npx vite --host                     # frontend / 前端

Open http://localhost:5173 — you should see the demo app with clone, status, commit, and branch management.

打开 http://localhost:5173 —— 你会看到包含 clone、status、commit 和分支管理的演示应用。


Usage / 使用方式

ES Proxy Client (Vanilla JS/TS)

import { createGitProxy } from 'git-web-rpc/client'

const git = createGitProxy({ endpoint: '/api/git' })

await git.clone({ dir: '/repo', url: 'https://github.com/user/repo' })
const matrix = await git.statusMatrix({ dir: '/repo' })
await git.add({ dir: '/repo', filepath: 'README.md' })
await git.commit({
  dir: '/repo',
  message: 'hello from the browser',
  author: { name: 'Dev', email: 'dev@example.com' },
})

React Hooks

import { GitProvider, useStatusMatrix, useGitCommit } from 'git-web-rpc/client/hooks'

function App() {
  return (
    <GitProvider endpoint="/api/git">
      <StatusView dir="/repo" />
    </GitProvider>
  )
}

function StatusView({ dir }: { dir: string }) {
  const { data: matrix, loading } = useStatusMatrix(dir)
  const { mutate: commit } = useGitCommit()

  if (loading) return <p>Loading...</p>
  return (
    <div>
      <pre>{JSON.stringify(matrix, null, 2)}</pre>
      <button onClick={() => commit({
        dir,
        message: 'update',
        author: { name: 'Dev', email: 'dev@example.com' },
      })}>
        Commit
      </button>
    </div>
  )
}

Server — Next.js App Router

// app/api/git/route.ts
import { createNextAppRouteHandler } from 'git-web-rpc/server'
import fs from 'node:fs'

const { POST, GET } = createNextAppRouteHandler({ fsImpl: fs })
export { POST, GET }

Server — Express

import express from 'express'
import { createExpressMiddleware } from 'git-web-rpc/server'

const app = express()
app.use('/api/git', createExpressMiddleware())
app.listen(3001)

Server — Standalone CLI

npx git-rpc-serve --port 3001
Options:
  -p, --port <number>  Port to listen on (default: 3001, env: PORT)
  -h, --help           Show help
  -v, --version        Show version

WebContainers & OpenClaw Integration / 集成指南

git-web-rpc is purpose-built for browser-based development environments. Here's how it fits:

git-web-rpc 专为浏览器开发环境设计,以下是集成方式:

WebContainers

Run the git-rpc server inside a WebContainer. Connect the Proxy client from your editor UI. Full Git — clone, commit, push — without ever leaving the browser sandbox.

在 WebContainer 中运行 git-rpc 服务端,从编辑器 UI 连接 Proxy 客户端。完整的 Git 能力 —— clone、commit、push —— 无需离开浏览器沙箱。

// Inside your WebContainer boot script
// 在 WebContainer 启动脚本中
const serverProcess = await webcontainer.spawn('npx', ['git-rpc-serve', '--port', '3001'])

// In your editor UI
// 在编辑器 UI 中
const git = createGitProxy({ endpoint: `${webcontainerUrl}/api/git` })
await git.clone({ dir: '/project', url: repoUrl })

OpenClaw

Drop in the React hooks to add Git panels to your AI-powered coding interface. The useStatusMatrix hook auto-refreshes via SSE when files change — no polling needed.

直接使用 React Hooks 为 AI 编程界面添加 Git 面板。useStatusMatrix 通过 SSE 自动刷新 —— 无需轮询。

import { GitProvider, useStatusMatrix, useGitCommit, useGitClone } from 'git-web-rpc/client/hooks'

// Wrap your app / 包裹你的应用
<GitProvider endpoint="/api/git">
  <YourAICodingUI />
</GitProvider>

Sandbox Isolation / 沙箱隔离

For multi-user environments, use SandboxManager to give each session its own isolated memfs volume:

多用户环境下,使用 SandboxManager 为每个会话提供独立的 memfs 虚拟文件系统:

import { SandboxManager } from 'git-web-rpc/server'

const manager = new SandboxManager({
  maxSessions: 50,
  idleTimeoutMs: 30 * 60 * 1000,
  onPersist: async (sessionId, json) => { /* save to Redis/DB */ },
  onRestore: async (sessionId) => { /* load from Redis/DB */ },
})

API Reference / API 参考

Git Operations / Git 操作

Operation Type Description / 描述
status read File status / 文件状态
statusMatrix read Full working tree status / 完整工作树状态
log read Commit history / 提交历史
currentBranch read Current branch name / 当前分支名
listBranches read All local branches / 所有本地分支
listFiles read Files tracked in index / 索引中的文件
readBlob read Read file content by OID / 按 OID 读取文件
clone write Clone a remote repo / 克隆远程仓库
init write Initialize a new repo / 初始化仓库
add write Stage files / 暂存文件
remove write Remove files from index / 从索引移除
commit write Create a commit / 创建提交
branch write Create a branch / 创建分支
deleteBranch write Delete a branch / 删除分支
checkout write Switch branches / 切换分支
fetch network Fetch from remote / 拉取远程
push network Push to remote / 推送到远程
pull network Pull from remote / 拉取并合并
resetIndex write Unstage a file / 取消暂存

React Hooks

Hook Returns Description / 描述
useStatusMatrix(dir) { data, loading, error, refresh } Working tree status (auto-refreshes via SSE) / 工作树状态(SSE 自动刷新)
useGitLog(dir, depth?) { data, loading, error, refresh } Commit history / 提交历史
useGitStatus(dir, filepath) { data, loading, error, refresh } Single file status / 单文件状态
useBranch(dir) { data, loading, error, refresh } Current branch / 当前分支
useBranches(dir) { data, loading, error, refresh } All branches / 所有分支
useListFiles(dir) { data, loading, error, refresh } Tracked files / 已跟踪文件
useGitClone() { mutate, loading, error } Clone operation / 克隆操作
useGitInit() { mutate, loading, error } Init operation / 初始化操作
useGitAdd() { mutate, loading, error } Stage files / 暂存文件
useGitCommit() { mutate, loading, error } Commit / 提交
useGitCheckout() { mutate, loading, error } Checkout branch / 切换分支
useGitBranch() { mutate, loading, error } Create branch / 创建分支
useGitResetIndex() { mutate, loading, error } Unstage file / 取消暂存

Proxy Client Options / 客户端配置

createGitProxy({
  endpoint: '/api/git',           // RPC endpoint
  eventsEndpoint: '/api/git/events', // SSE endpoint for progress
  timeout: 30000,                 // Request timeout (ms)
  onProgress: (event) => {},      // Progress callback for network ops
  onRequest: (req) => req,        // Request interceptor (e.g. add auth headers)
  onResponse: (res) => {},        // Response interceptor (e.g. error reporting)
})

Project Structure / 项目结构

git-web-rpc/
├── packages/
│   ├── shared/types.ts          # Shared type definitions / 共享类型
│   ├── client/
│   │   ├── gitProxy.ts          # ES Proxy RPC client / ES Proxy 客户端
│   │   ├── hooks/useGit.tsx     # React hooks / React Hooks
│   │   └── components/          # Ready-made UI components / 预制 UI 组件
│   └── server/
│       ├── gitRouter.ts         # RPC router + method whitelist / RPC 路由
│       ├── httpAdapter.ts       # HTTP adapters (Node/Express/Next) / HTTP 适配器
│       ├── gitSandbox.ts        # Per-session memfs isolation / 沙箱隔离
│       ├── fileWatcher.ts       # Chokidar file watcher / 文件监听
│       ├── statusNotifier.ts    # SSE status push / SSE 状态推送
│       └── cli.ts               # CLI entry point / CLI 入口
├── web/                         # Demo app (Vite + React) / 演示应用
├── docs/                        # Architecture docs / 架构文档
└── __tests__/                   # Unit + property-based tests / 测试

Contributing / 贡献

Contributions are welcome! / 欢迎贡献!

  1. Fork the repo / Fork 本仓库
  2. Create a feature branch / 创建特性分支 (git checkout -b feat/amazing-feature)
  3. Commit your changes / 提交更改
  4. Open a Pull Request / 发起 PR

Please run tests before submitting / 提交前请运行测试:

npm test
npm run typecheck

License / 许可证

MIT


Made for the browser. Powered by isomorphic-git.

为浏览器而生,由 isomorphic-git 驱动。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors