Skip to content

emersonding/local-arc

Repository files navigation

Local Arc

Small, standalone and local-only tooling for create a preview diff with a git diff cmd in phabricator style (include unstaged or untracked files).

AI friendly: user & ai can read & comment diffs, achieve a local review loop between users and AI coding agents.

Local Arc ticket review screenshot

Local Arc ticket list screenshot

Highlights

  • Create local arc-like git diffs with a git-like diff cmd, into a saved & browser-reviewable tickets.
  • Expand changed-block context on demand when reference snapshots are available.
  • Support inline comments & reply comment.
  • Show comment counts in the file tree while reviewing a diff.
  • Update an existing ticket with --update while preserving comments and earlier revisions.
  • View patches with side-by-side or unified diff modes, file navigation, etc.
  • Add editable titles, Markdown summaries, and comment activity.

Install or Link the CLI

Install the published CLI:

npm install -g local-arc

For local development, link it from this directory:

npm link

That exposes the local-arc command.

Tip: arc alias

For a near-arc local workflow, add an alias: alias arc='local-arc'

Then a diff can be opened with: arc diff HEAD~1

Diff

local-arc diff HEAD~1

This runs git diff HEAD~1, captures the output into a temporary patch file under /tmp/local-arc/<ticket_id>/diff.patch, writes reference snapshots when the changed files can be read, serves the browser view, and opens the URL in your default browser. The <ticket_id> is T plus six digits, so the browser URL also identifies the saved patch path, for example http://127.0.0.1:7788/T153871/ maps to /tmp/local-arc/T153871/diff.patch.

The workflow is similar to arc diff in the sense that both start from a local working-copy diff and turn it into a reviewable change. The difference is that arc diff submits that change to Phabricator, while local-arc diff keeps everything local: it runs the Git diff command you provide, opens a local browser viewer, and does not create or update a remote review.

diff prepends git diff unless the first argument is git:

local-arc diff
local-arc diff --cached
local-arc diff HEAD~1 -- README.md
local-arc diff 'git -C /path/to/repo diff HEAD~1'

For common commands like git diff HEAD~1, the viewer infers HEAD~1 as the old-side source for on-demand context expansion.

When a diff compares the current working tree to another revision, local-arc asks whether untracked files should be included as full new-file hunks. Staged and commit-to-commit diffs skip that prompt by default. Use --include-untracked or --no-include-untracked to force either behavior.

Update Diff

Use --update to update a ticket.

local-arc diff HEAD~1 --update T153871

The ticket ID, title, summary, comments, and activity file are preserved. Inline comment ranges are adjusted best-effort when reference snapshots are available: Local Arc first looks for the same selected source lines in the updated file, then falls back to unique-line anchors. Comments on files that disappear remain in the comment store and are marked file-gone.

Use --no-open when running in scripts or tests:

local-arc diff HEAD~1 --no-open

Add Metadata to a Diff

local-arc diff HEAD~1 \
  --title "Checkout diff" \
  --description "Review notes in **Markdown**."

The --title and --description fields are optional. If either is present, the viewer shows a metadata section above the file diffs. When --title is omitted, Local Arc uses the project name. When --description is omitted, the description starts empty and can be edited in the viewer.

Inline comment changes are also recorded in diff.patch.activities.json. Comments and replies include a role field, which defaults to user; agents can set values such as claude or codex when they write comments through the local comment API.

Saved Ticket Files

Default file dir is /tmp/local-arc. To use a different diff temp directory:

local-arc config set-dir /path/to/local-arc-files
local-arc config dir

config set-dir writes to ~/.local-arc/config.json. config dir prints the directory used by diff. Generated diff tickets are saved under <dir>/<ticket_id>/, with the patch at <dir>/<ticket_id>/diff.patch.

A saved diff ticket directory contains the current patch, ticket metadata, and patch-specific sidecars:

<dir>/
└── T153871/
    ├── diff.patch                    # Current patch shown by the ticket URL.
    ├── diff.patch.refs.json          # Old/new file snapshots for context expansion and comment remapping.
    ├── diff.patch.comments.json      # Inline comments and replies.
    ├── diff.patch.activities.json    # Editable title, summary, and comment activity.
    ├── metadata.json                 # Ticket ID, project, repo, command, current revision, and revision history.
    └── revisions/                    # Read-only archived revisions created by --update.
        └── 1/
            ├── diff.patch
            ├── diff.patch.refs.json
            ├── diff.patch.comments.json
            └── diff.patch.activities.json

When a ticket is updated, the previous current patch and its sidecars are copied into revisions/<number>/, then the top-level diff.patch and sidecars are replaced with the new current revision. Historical revisions can be opened from the viewer with ?revision=<number> and are read-only.

Save a Patch

local-arc diff HEAD~1 --out /tmp/head-1.patch

The Git command stdout is written directly to the patch file. Git statuses 0 and 1 are treated as successful captures because some diff forms return 1 when differences are present. When the changed files can be read, diff --out also writes <patch-file>.refs.json with original and new file snapshots. The viewer uses that sidecar for on-demand context expansion, so the patch can be opened later without access to the original repo.

Useful inputs:

local-arc diff --out /tmp/worktree.patch
local-arc diff --cached --out /tmp/staged.patch
local-arc diff main...HEAD --out /tmp/base.patch
local-arc diff --repo /path/to/repo HEAD~1 --out /tmp/head.patch

Open a Patch

local-arc open /tmp/head-1.patch

Then open:

http://127.0.0.1:7788/

If 7788 is already in use, the viewer automatically tries the next available port and prints the URL to open. Use --strict-port if you want it to fail instead. Use --no-open to print the URL without opening it.

For saved diff tickets, open also accepts the ticket directory or its diff.patch file and opens the ticket URL:

local-arc open /tmp/local-arc/T153871
local-arc open /tmp/local-arc/T153871/diff.patch

Both forms serve the viewer at:

http://127.0.0.1:7788/T153871/

The browser view supports:

  • side-by-side and unified display
  • per-file navigation
  • file filtering
  • line numbers and add/delete coloring
  • simple intraline highlights for paired replacements
  • on-demand changed-block context expansion when reference snapshots are available

diff --out writes a .refs.json sidecar next to the patch when it can read the changed files. open uses that sidecar to show +20 before and +20 after buttons around changed blocks. If the sidecar is missing, those buttons are hidden by default.

For a saved patch without a .refs.json sidecar, pass repo context when you want the webpage to load more lines around changed blocks:

local-arc open /tmp/head-1.patch --repo . --base HEAD~1

Then click +20 before or +20 after next to a changed block.

List Saved Diff Tickets

local-arc list
local-arc list T153871

This prints saved T-prefixed numeric diff tickets from the configured diff directory. Without a ticket ID, the command prints a terminal table with the ticket ID, creation timestamp, Git root name when it can be inferred, title, project directory, and ticket directory. With a ticket ID, it prints detailed metadata for that saved diff, including the ticket directory, command, description, comments, and revisions.

To browse saved diffs in the local web viewer, use:

local-arc browse

This opens a local browser page with the same saved tickets, including the project directory and ticket directory columns. Click a ticket ID to open that saved diff in the viewer.

Local Arc and AI Agents

Local Arc can be used as a local review ticket between a person and an AI coding agent. Create a saved ticket with a title and description, then share the ticket URL or ticket directory with the agent:

local-arc diff HEAD~1 \
  --title "Fix checkout totals" \
  --description "Review the tax and discount calculation changes."

The browser opens a ticket URL such as:

http://127.0.0.1:7788/T153871/

Use the viewer to add inline comments on changed lines. Then ask the agent to inspect the saved ticket, address the comments in the repo, and reply to each handled comment. The agent can read comments from <dir>/<ticket_id>/diff.patch.comments.json and review ticket activity in <dir>/<ticket_id>/diff.patch.activities.json.

When an agent writes through the local comment API, it should set role to its agent name, such as codex or claude, so replies and activity entries show who made them:

{
  "parentId": "comment-id",
  "text": "Fixed in the working tree and verified with the focused test.",
  "role": "codex"
}

After applying fixes, update the same ticket instead of creating a new one:

local-arc diff HEAD~1 --update T153871

--update preserves the ticket, comments, replies, and activity while replacing the current patch. The viewer keeps earlier revisions available from the Revisions section, so the user can compare the original comments with the latest patch.

Command Reference

local-arc diff [git-diff-args...] [--title <title>] [--description <markdown>] [--host 127.0.0.1] [--port 7788] [--no-open]
local-arc diff [git-diff-args...] --out <patch-file> [--repo <path>] [--title <title>] [--description <markdown>]
local-arc diff [git-diff-args...] --update T123456 [--title <title>] [--description <markdown>] [--host 127.0.0.1] [--port 7788] [--no-open]
local-arc open <patch-file-or-ticket-dir> [--host 127.0.0.1] [--port 7788] [--no-open] [--repo <path>] [--base <rev>] [--head <rev>]
local-arc list [T123456]
local-arc browse [--host 127.0.0.1] [--port 7788] [--no-open]
local-arc config set-dir <dir>
local-arc config dir
local-arc render --patch <patch-file> --out <html-file>
local-arc ai-doc

Run local-arc ai-doc to print the AI-agent workflow, including create/update guidance, the recommended Why/What/Test description sections, diff-scope flags, and how agents should inspect and reply to user comments. Point your agent at this command so it can self-discover the convention.

About

A pure local diff viewer - view any git diff command in a phabricator-like diff view. For phabricator, you create a diff with `arc diff main` and view it on phabricator server, with this tool you run `local-arc diff 'git diff head~1'` and view diff in browser with a local server

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages