# How π‑Web Integrates Git Diff and Status Information with the Agent

> Discover how pi-web seamlessly integrates Git diff and status information with the Agent. Learn about its RESTful endpoints and tool call capabilities for efficient repository management.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: deep-dive
- Published: 2026-07-24

---

**π‑Web exposes RESTful endpoints that parse porcelain Git output, allowing the Agent to query repository status and file diffs via tool calls bridged through an RPC manager.**

The `agegr/pi-web` repository implements a bidirectional integration where server-side Git parsers feed real-time repository data to the conversational Agent. This architecture enables the Agent to understand code changes, display file statuses in the UI, and generate diff previews within the chat context.

## Git Status and Diff API Architecture

π‑Web provides two HTTP endpoints that securely expose Git operations to the Agent layer. Both routes validate that the supplied `cwd` parameter is an absolute, allowed path before executing any Git commands.

### Repository Status Endpoint (`/api/git/status`)

The status endpoint defined in [`app/api/git/status/route.ts`](https://github.com/agegr/pi-web/blob/main/app/api/git/status/route.ts) accepts a `cwd` query parameter and returns a structured JSON representation of the working directory state. It delegates processing to `getGitStatus()` in [`lib/git-changes.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-changes.ts), which executes `git status --porcelain=v1 -z` to obtain machine-readable output.

### File Diff Endpoint (`/api/git/diff`)

Located in [`app/api/git/diff/route.ts`](https://github.com/agegr/pi-web/blob/main/app/api/git/diff/route.ts), this endpoint requires both `cwd` and `filePath` parameters. It invokes `getGitFileDiff()` from [`lib/git-changes.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-changes.ts) to generate either a unified diff against `HEAD` or a synthetic patch for newly added files. The implementation rejects responses that lack proper diff headers (`@@`), ensuring only valid patch data reaches the Agent.

## Backend Parsing and Classification

The backend transforms raw Git CLI output into structured data that the Agent can reason about programmatically.

### Parsing Porcelain Status Output

In [`lib/git-status.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-status.ts), the `parseGitPorcelainV1()` function consumes the null-separated output from Git and constructs `GitPorcelainEntry` objects. The `classifyGitStatus()` helper then maps the two-character index/work-tree status codes to concise `{status, code}` pairs (lines 10‑47). This classification allows the Agent to interpret whether files are modified, staged, untracked, or deleted without parsing Git strings itself.

### Generating Unified Diffs

The `getGitFileDiff()` function in [`lib/git-changes.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-changes.ts) (lines 57‑64, 124‑163) handles four distinct file states: untracked, added, modified, and deleted. For untracked or added files, it constructs a synthetic "added file" patch directly from disk content. For tracked modifications, it executes `git diff` against `HEAD`. The function enforces size limits and validates patch headers before returning the diff text.

## Agent Integration Flow

The Agent communicates with Git functionality through a structured tool-calling interface rather than executing shell commands directly.

### Tool Preset and Tool Calls

π‑Web’s Agent is wired to a tool preset that registers `git_status` and `git_diff` as available capabilities. When a user asks about repository changes, the Agent emits a JSON tool call payload:

```json
{
  "toolCallId": "t1",
  "toolName": "git_status",
  "input": { "cwd": "/home/user/project" }
}

```

### RPC Manager Bridging

The [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) module intercepts these tool calls and translates them into HTTP requests to the appropriate API endpoints. After the server returns the JSON response (either status arrays or diff patches), the RPC manager feeds the data back into the Agent's context window. The Agent then incorporates this Git metadata into its reasoning chain and can trigger UI updates, such as rendering diff previews in the chat window via [`MessageView.tsx`](https://github.com/agegr/pi-web/blob/main/MessageView.tsx).

## Client-Side Implementation Examples

You can interact with these APIs directly from React components or through the Agent's tool interface.

**Fetching repository status from a component:**

```typescript
// In a React component (e.g., SessionSidebar)
const cwd = '/home/user/project';
fetch(`/api/git/status?cwd=${encodeURIComponent(cwd)}`)
  .then(r => r.json())
  .then((status) => {
    // `status.files` is an array of {filePath, status, code, …}
    console.log('Repo status:', status);
  });

```

**Requesting a diff via the Agent tool protocol:**

```typescript
// Agent tool call payload (generated automatically by the Agent)
{
  toolName: "git_diff",
  input: {
    cwd: "/home/user/project",
    filePath: "/home/user/project/src/main.ts"
  }
}

```

**Rendering the diff in the chat interface:**

```tsx
// Inside MessageView.tsx
if (msg.type === 'toolResult' && msg.toolName === 'git_diff') {
  return <MarkdownBody>{msg.content.patch}</MarkdownBody>;
}

```

## Summary

- **Dual API Surface**: π‑Web exposes `GET /api/git/status` and `GET /api/git/diff` endpoints that validate absolute paths before executing Git commands.
- **Porcelain Parsing**: The [`lib/git-status.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-status.ts) module parses `git status --porcelain=v1 -z` output and classifies entries into structured status objects.
- **Diff Generation**: [`lib/git-changes.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-changes.ts) generates unified diffs or synthetic patches for added files, validating headers before returning data.
- **Agent Bridge**: [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) translates Agent tool calls into HTTP requests, enabling the Agent to query Git state without direct repository access.
- **UI Integration**: Git data flows back to the Agent context and can be rendered in the file explorer (status icons) or chat window (diff previews).

## Frequently Asked Questions

### How does the Agent trigger Git status checks in π‑Web?

The Agent emits a tool call with `toolName: "git_status"` and a `cwd` parameter. The [`rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/rpc-manager.ts) module receives this call and forwards it as an HTTP GET request to `/api/git/status?cwd=<path>`. The server validates the path, executes `getGitStatus()`, and returns the parsed status JSON back to the Agent's context.

### What Git output format does π‑Web parse for status information?

According to the source code in [`lib/git-changes.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-changes.ts), π‑Web uses `git status --porcelain=v1 -z` to obtain null-separated, machine-readable status output. The `parseGitPorcelainV1()` function in [`lib/git-status.ts`](https://github.com/agegr/pi-web/blob/main/lib/git-status.ts) then processes this format to extract file paths and two-character status codes.

### How does π‑Web handle diff generation for untracked files?

When `getGitFileDiff()` encounters an untracked or newly added file, it constructs a synthetic patch directly from the file's disk content rather than running `git diff`. This ensures the Agent receives a valid unified diff format even for files not yet tracked by Git, provided the patch contains the required `@@` header lines.

### What validation prevents unauthorized path access in the Git APIs?

Both [`app/api/git/status/route.ts`](https://github.com/agegr/pi-web/blob/main/app/api/git/status/route.ts) and [`app/api/git/diff/route.ts`](https://github.com/agegr/pi-web/blob/main/app/api/git/diff/route.ts) implement path validation to ensure the supplied `cwd` parameter is an absolute path within an allowed directory. This prevents path traversal attacks and restricts Git operations to authorized working directories only.