Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ jobs:
with:
node-version-file: .node-version
cache: pnpm
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
cache: true
- run: pnpm install --frozen-lockfile
- run: pnpm --filter @servediff/web exec playwright install --with-deps chromium
- run: pnpm check:js
Expand Down Expand Up @@ -55,5 +59,5 @@ jobs:
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: go run ./tools/stage-web apps/web/dist internal/webui/assets
- run: mkdir -p dist && go build -trimpath -o dist/servediff-go ./cmd/servediff
- run: mkdir -p dist && go build -trimpath -o dist/servediff ./cmd/servediff
- run: pnpm test:conformance
2 changes: 2 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ builds:
binary: servediff
env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.version={{.Version}}
goos: [linux, darwin, windows]
goarch: [amd64, arm64]

Expand Down
2 changes: 1 addition & 1 deletion DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ measured elements or replace the application tokens with framework defaults.
file-kind hints. They are a bounded categorical palette, not extra UI accents.
- Status always includes text, a sign, an icon, or a shape. Preserve staging's
empty/half/full dot distinction; its half-fill is information, not decoration.
- CPU and RAM in the status bar describe the ServeDiff Node server process, not
- CPU and RAM in the status bar describe the ServeDiff server process, not
the browser or whole machine. Keep that scope explicit in the tooltip.
- Pierre owns syntax colors, changed-line fills, word highlights, line selection,
and code-theme surfaces. App status tokens govern the surrounding UI only.
Expand Down
124 changes: 35 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,118 +1,64 @@
# servediff

Review local Git changes in your browser. Built with React, Vite, Tailwind CSS v4,
[shadcn/ui](https://ui.shadcn.com) on Base UI, and
[Pierre diffs](https://diffs.com); inspired by diffshub and
[diffx](https://github.com/wong2/diffx).

## Setup

Requires **Node 26**, **pnpm 11**, and **Git**. Developing or building the
parallel Go implementation also requires **Go 1.25**. From this checkout:

```sh
pnpm install
pnpm build
pnpm add -g .
```

This registers `servediff` globally, pointing to this checkout. Keep the checkout in place. If pnpm reports a missing global bin directory, run `pnpm setup`, restart your terminal, and retry.
Review local Git changes in your browser without modifying your working tree or
index.

## Usage

From any Git repository:
Run from a Git repository:

```sh
servediff .
```

servediff automatically opens the local address in your browser on macOS and
Linux, except in SSH sessions. Stop with **Ctrl+C**. The network address is
reachable by other devices on your local network.
You can also serve another repository or choose the address:

```sh
servediff . # current repository
servediff /path/to/repo # another repository
servediff . --port 4000 # different port
```

Subdirectories resolve to the repository root. Switch between all, staged, and unstaged changes; edits refresh automatically. Use the file tree to navigate and **+** beside a line to comment. **Copy unresolved** or **Copy all** exports agent-ready XML with instructions, short comment IDs, captured code context, and review provenance. Comments and reviewed-file marks persist through the local server; display preferences stay in your browser. The viewer never changes your Git files or index.

Or pipe Git output directly:

```sh
git diff | servediff
git show | servediff
git show main..HEAD~1 | servediff
git diff main HEAD~1 | servediff
servediff - < saved.patch
servediff /path/to/repo
servediff . --port 4000
servediff . --host 0.0.0.0
```

Piped or redirected input takes priority over a directory argument; an empty pipe opens an empty diff. Without input redirection, a directory is required. Piped diffs are fixed snapshots; re-run the command to update. Commit ranges show each commit separately, including repeated files. `git diff` between two refs shows their net difference. Standard Git patches up to 16 MiB total / 2 MiB per file are supported; use `git show --diff-merges=separate` for merge commits.
By default, servediff binds to `127.0.0.1`, opens a browser, and uses the first
available port from 7981 through 7990. Stop it with **Ctrl+C**.

## Development
Passing `--host 0.0.0.0` exposes the unauthenticated server on every network
interface and accepts any HTTP host name. Use it only on a trusted network.

From this checkout:
## Reviewing changes

```sh
pnpm dev:web
pnpm dev:server
```
Switch between all, staged, and unstaged changes. Use the file tree to navigate,
mark files as reviewed, and select **+** beside a line to comment. **Copy
unresolved** and **Copy all** export review comments as agent-ready XML.

Both development commands use `test/fixtures/sample.diff`. The web workspace
runs the production API handler with an in-memory fixture store preloaded with
comments and reviewed-file state; the server workspace runs the Node CLI with
the same diff piped to stdin.
Comments and reviewed-file marks persist by repository. Display preferences stay
in the browser.

The repository also contains a contract-compatible Go server. It coexists with
the Node server while parity is verified; the Node implementation remains the
published `servediff` command.

```sh
task dev # Go API with fixture data + Vite HMR
task dev:go # standalone Go server with built web UI
task build:go # dependency-free dist/servediff-go binary
task check # JavaScript, Go, and cross-server conformance
```
## Piped diffs

Without [Task](https://taskfile.dev), equivalent `pnpm` and `go` commands are
listed in `Taskfile.yml`. The built Go binary accepts a repository path, piped
patch, or `--fixture`; use `--state memory` for isolated development/tests.

Install Chromium once, then test either workspace independently or run every
check from the root:
Serve a fixed Git patch instead of a live repository:

```sh
pnpm test:browser:install
pnpm --filter @servediff/server test
pnpm --filter @servediff/web test
pnpm check
git diff | servediff
git show | servediff
git show main..HEAD~1 | servediff
servediff - < saved.patch
```

Run `pnpm build` after frontend changes, then restart `servediff`. No global reinstall needed.

See [docs/architecture.md](docs/architecture.md) for workspace boundaries and
[ADR 0001](docs/adr/0001-polyglot-monorepo.md) for the migration decision.
Piped input takes priority over a directory argument. Re-run the command to
refresh a piped diff. Standard Git patches are limited to 16 MiB total and 2 MiB
per file. For merge commits, use `git show --diff-merges=separate`.

UI work follows [DESIGN.md](DESIGN.md). Existing semantic tokens in
`apps/web/src/tokens.css` remain canonical and are mapped into Tailwind/shadcn
theme roles by the global stylesheet. Reuse repository-owned primitives in
`apps/web/src/components/ui`; reserve authored CSS for specialized layout,
dynamic geometry, and Pierre's measured rendering boundary.
## API and data

`App.tsx` composes the page sections. `app-state.tsx` owns shared state through
`AppProvider`; `DiffWorkspace.tsx` owns Pierre rendering, and `use-review.ts`
uses the generated REST client. Section-only state stays with its component.
The OpenAPI 3.1 contract is served at `/openapi.yaml`; REST endpoints are under
`/api/v1`.

## API
The API is unauthenticated. Browser same-origin and cross-site checks remain, but
anyone who can reach the server can access its review data.

The server prints a per-run API token and includes it in browser URLs as a URL
fragment. REST clients send it as `Authorization: Bearer <token>`. The OpenAPI
3.1 contract is available at `/openapi.yaml`; regenerate the TypeScript client
after contract changes with `pnpm generate:api`.
Review data is stored under `$XDG_STATE_HOME/servediff/reviews`, or
`~/.local/state/servediff/reviews` when `XDG_STATE_HOME` is unset.

The versioned API exposes the active source, current diff snapshots, file
patches and contents, comment CRUD/export, and reviewed-file marks under
`/api/v1`. Piped input supports only the `all` scope and remains immutable.
Comments persist by source under `$XDG_STATE_HOME/servediff/reviews` (or
`~/.local/state/servediff/reviews`).
For source setup, development commands, and architecture, see
[docs/development.md](docs/development.md).
42 changes: 14 additions & 28 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,43 @@ tasks:
cmds:
- go run ./tools/stage-web apps/web/dist internal/webui/assets

build:node:
cmds:
- pnpm build

build:go:
build:
cmds:
- task: generate
- task: web:stage
- mkdir -p dist
- go build -trimpath -o dist/servediff-go ./cmd/servediff
- go build -trimpath -o dist/servediff ./cmd/servediff

build:
install:
cmds:
- task: build:node
- go run ./tools/stage-web apps/web/dist internal/webui/assets
- mkdir -p dist
- go build -trimpath -o dist/servediff-go ./cmd/servediff
- task: build
- |
if [ "$(pnpm list --global --depth 0 --parseable servediff-workspace | wc -l)" -gt 1 ]; then
pnpm remove --global servediff-workspace
fi
- go run ./tools/remove-legacy-install
- go install -trimpath ./cmd/servediff

dev:web:
cmds:
- pnpm dev:web

dev:node:
cmds:
- pnpm dev:server

dev:go:
dev:server:
deps: [web:build]
cmds:
- go run ./cmd/servediff --fixture test/fixtures/sample.diff --state memory --web-dir apps/web/dist

dev:go-api:
cmds:
- go run ./cmd/servediff --fixture test/fixtures/sample.diff --state memory --no-auth --no-browser --port 3333

dev:web-go:
env:
SERVEDIFF_API_URL: http://127.0.0.1:3333
cmds:
- pnpm dev:web

dev:
deps: [dev:go-api, dev:web-go]
cmds:
- task: dev:web

test:go:
cmds:
- go test ./...

test:conformance:
cmds:
- task: build:go
- task: build
- pnpm test:conformance

check:go:
Expand Down
22 changes: 0 additions & 22 deletions apps/server/package.json

This file was deleted.

Loading
Loading