A small web dashboard that visualizes the results of a daily git-sync job: which of your local repos are up to date, which were merged, which had conflicts, which were skipped due to uncommitted changes.
The repo ships two things:
launchd/— a macOS LaunchAgent template that runs thegit-syncskill daily at 8:00 AM.- The dashboard itself — an Express app served via Docker on
http://localhost:3333, reading the skill's log files.
The git-sync skill it depends on lives in a separate repository — see Prerequisite below.
- Current snapshot — counts (Conflicts / Skipped / Updated / Merged) and per-repo status from the most recent run.
- History · last 7 days — collapsible cards for every earlier run in the rolling 7-day log.
Status legend:
| Status | Meaning |
|---|---|
UPDATED |
master/main was pulled and had new commits |
MERGED+PUSH |
master/main merged into a feature branch and pushed to upstream |
MERGED |
merged into a feature branch (no upstream, or push failed) |
UNCHANGED |
already up to date |
SKIPPED |
git refused (e.g. uncommitted changes would be overwritten, dirty staging branch) |
CONFLICT |
merge attempted but aborted due to conflicts |
TO-DEFAULT |
was on a staging branch, switched to master/main |
UNREACHABLE |
workspace path missing or unreadable (often a macOS Full Disk Access issue) |
This dashboard reads the log files produced by the git-sync skill. Install that first so the script lives at ~/.claude/skills/git-sync/git-sync.sh:
Skill source:
<REPLACE-WITH-SKILL-REPO-URL>
Once the skill is in place, run a sync at least once so the log files exist:
bash ~/.claude/skills/git-sync/git-sync.shgit clone https://github.com/aaron-wego/git-sync-dashboard.git
cd git-sync-dashboard
./install.shinstall.sh will:
- Verify the skill is installed at
~/.claude/skills/git-sync/git-sync.sh(fails fast otherwise). - Render the LaunchAgent plist with your
$HOMEandlaunchctl loadit. - Run
docker compose up -d --buildfor the dashboard.
Then open http://localhost:3333.
Edit ~/.claude/skills/git-sync/workspaces.txt — one absolute path per line, # comments allowed, ~ and $HOME are expanded.
~/go-workspace
~/js-workspace
~/IdeaProjects
macOS gotcha: if you keep workspaces under
~/Desktop,~/Documents, or~/Downloads, the LaunchAgent will silently fail to read them because of macOS TCC (Privacy & Security). Either grant/bin/bashFull Disk Access, or move the workspaces to your home directory. The script logsUNREACHABLEfor any path it can't see.
bash ~/.claude/skills/git-sync/git-sync.shThis appends a fresh entry to ~/.claude/skills/git-sync/git-sync.log and refreshes git-sync-latest.log. The dashboard re-reads these on every page load.
The script keeps a rolling 7 days of report blocks in git-sync.log. Each run appends its block; older blocks are pruned in place based on the Run at: date. The history endpoint (/api/history) parses the file into structured runs for the UI.
./uninstall.shUnloads and removes the LaunchAgent, and stops the dashboard container. Skill files and logs at ~/.claude/skills/git-sync/ are left in place — delete that directory manually if you want a clean wipe.
.
├── docker-compose.yml # mounts ~/.claude/skills/git-sync as /app/data:ro
├── Dockerfile # node:20-alpine + express
├── server.js # parses log files, serves /api/status + /api/history
├── public/index.html # single-page dashboard UI
├── launchd/
│ └── com.user.git-sync.plist.template # __HOME__ substituted at install time
├── install.sh
└── uninstall.sh
- macOS (LaunchAgent is macOS-specific; the dashboard itself runs anywhere Docker does)
- Docker Desktop or equivalent (for the dashboard)
bash,git, and BSDdate(already on macOS)- Optional:
timeoutviabrew install coreutilsis not required — the script usestimeoutfrom coreutils if available, otherwise BSD'stimeout(macOS Sequoia+ ships it). On older macOS,brew install coreutilsand linkgtimeoutastimeout.