|
1 | 1 | # Powergit |
2 | 2 |
|
3 | | -Powergit is a local-first Git explorer that mirrors repositories into PowerSync so you can browse branches, files, and commit history through a fast, reactive UI—no external network calls required once synced. |
| 3 | +Powergit is a local-first Git explorer that mirrors repositories into Supabase (Postgres + Storage) and streams metadata to the UI via PowerSync, so you can browse branches, files, and commit history from a fast local replica. |
4 | 4 |
|
5 | | -## Run Locally |
| 5 | +## Quick start (local dev) |
6 | 6 |
|
7 | 7 | ```bash |
8 | 8 | pnpm install |
9 | | -pnpm dev:stack:up |
| 9 | +pnpm dev:stack |
| 10 | +``` |
| 11 | + |
| 12 | +In another terminal: |
| 13 | + |
| 14 | +```bash |
10 | 15 | pnpm dev |
11 | 16 | ``` |
12 | 17 |
|
13 | | -## Run prod locally |
| 18 | +## Quick start (prod-like) |
14 | 19 |
|
15 | 20 | ```bash |
16 | 21 | pnpm install |
17 | | -pnpm dev:prod |
| 22 | +pnpm dev:prod |
18 | 23 | ``` |
19 | 24 |
|
20 | | -> `pnpm dev:prod` uses `.env.prod` (remote Supabase/PowerSync). Use `pnpm dev:stack` if you want a local Docker-backed stack. |
| 25 | +> `pnpm dev:prod` uses `.env.prod` (remote Supabase/PowerSync). Use `pnpm dev` + `pnpm dev:stack` for a local Docker-backed stack. |
21 | 26 |
|
22 | 27 | ## Demos |
23 | 28 |
|
24 | | -### Create a repo from the CLI |
| 29 | +### 1) Create a repo from the CLI |
25 | 30 |
|
26 | 31 | https://github.com/user-attachments/assets/e05f20bb-78f5-4a7b-acc9-f662a9ac8a66 |
27 | 32 |
|
28 | | - |
29 | 33 | Create a repo and push to it using the `powergit::` remote from your terminal. |
30 | 34 |
|
31 | | -### Observe the created repo in Explorer |
| 35 | +### 2) Observe the created repo in Explorer |
32 | 36 |
|
33 | 37 | https://github.com/user-attachments/assets/67746738-34cc-4275-b0ae-39985af9b907 |
34 | 38 |
|
35 | 39 | Browse branches, files, and history once the repo has been mirrored into PowerSync. |
36 | 40 |
|
37 | | -### Explore a Github repository |
| 41 | +### 3) Clone a GitHub repo (mirror into PowerSync) |
38 | 42 |
|
39 | 43 | https://github.com/user-attachments/assets/5052ef0e-14f6-4428-b621-286e7e28bbd1 |
40 | 44 |
|
41 | | - |
42 | 45 | Clone a repository via `git clone powergit::/org/repo` and let the helper stream packs locally. |
43 | 46 |
|
44 | | -### Create an org |
45 | | - |
| 47 | +### 4) Create an org |
46 | 48 |
|
47 | 49 | https://github.com/user-attachments/assets/a11c560a-fd57-4a54-b6c6-3b51c5e1206b |
48 | 50 |
|
49 | | - |
50 | 51 | Create organizations (and later manage members/repos) directly from the Explorer UI. |
51 | 52 |
|
52 | 53 | ## How it works |
53 | | -In this repo we have built a custom git remote protocol that allows us to push git data into a Supabase database. We can later use PowerSync to see the data in the frontend. We use the powersync-tanstack-db package to query the database and show it reactively using the `@tanstack/powersync-db-collection` package. |
| 54 | +Powergit has two parts: |
54 | 55 |
|
55 | | -## Why PowerSync instead of TanStack DB alone |
56 | | -TanStack DB gives us a great query layer, but it does not include a sync engine or durable storage. PowerSync is the replicated store that keeps the Git metadata and pack metadata in step across the daemon and the explorer. |
| 56 | +- A Git remote helper (`git-remote-powergit`) that streams Git packs + metadata into Supabase when you push to a `powergit::...` remote. |
| 57 | +- An Explorer UI that subscribes to PowerSync streams and queries the local replica with TanStack DB (fast + offline after the first sync). |
| 58 | + |
| 59 | +### Import / clone flows |
| 60 | + |
| 61 | +#### Local daemon (dev/offline) |
| 62 | + |
| 63 | +1. Explorer calls your local daemon (`VITE_POWERSYNC_USE_DAEMON=true`) with a GitHub URL. |
| 64 | +2. The daemon clones from GitHub, then pushes to `powergit::/<org>/<repo>` (the helper uploads packs to Storage and writes metadata to Postgres). |
| 65 | +3. PowerSync replicates the tables to the browser; the UI becomes fully local for browsing. |
57 | 66 |
|
58 | | -- Offline-first persistence: PowerSync streams `refs`, `commits`, `file_changes`, and `objects` into SQLite (daemon) and IndexedDB (browser), so TanStack DB queries stay fast and continue to work without network access. |
59 | | -- Delta sync, not re-downloads: after the initial push of a large repo, only new refs/commits are streamed; the UI never has to resync the full history on each launch. |
60 | | -- Shared cache across surfaces: the daemon, CLI, and browser all query the same replicated tables via `@tanstack/powersync-db-collection`, avoiding bespoke cache plumbing while honoring the Supabase/PowerSync auth model. |
61 | | -- Pack handling: pack bytes stay in Supabase Storage while PowerSync ships the lightweight metadata we query. The explorer pulls packs lazily and indexes them locally, keeping PowerSync focused on the syncable metadata layer. |
| 67 | +#### Supabase Edge Function → GitHub Actions (hosted/prod) |
| 68 | + |
| 69 | +1. Explorer calls the Supabase Edge Function (`VITE_POWERSYNC_ACTIONS_IMPORT=true`). |
| 70 | +2. The function dispatches `.github/workflows/clone-and-push.yml`. |
| 71 | +3. GitHub Actions runs the Powergit daemon on the runner, clones the target repo, and pushes to `powergit::/<org>/<repo>`. |
| 72 | +4. Explorer follows progress via `import_jobs` (replicated by PowerSync) and can link to the Actions run. |
| 73 | + |
| 74 | +## Why PowerSync instead of TanStack DB alone |
| 75 | +TanStack DB is the query layer. PowerSync is the sync engine + durable local replica (SQLite/IndexedDB) that makes the Explorer fast and usable offline. |
62 | 76 |
|
63 | | -## Architecture Overview |
64 | | -At a high level the happy path looks like this: |
| 77 | +- PowerSync handles incremental replication of Git metadata (`refs`, `commits`, `file_changes`, `objects`). |
| 78 | +- The Explorer queries the same replica across sessions (no refetching full history on each load). |
| 79 | +- Pack bytes live in Supabase Storage and are downloaded/indexed lazily for file viewing. |
65 | 80 |
|
66 | | -1. **Import request (UI → daemon).** A user pastes a GitHub URL into the explorer. The frontend posts that payload to the local daemon. The daemon clones the repo, configures the custom `powergit::` remote, fetches every ref, and pushes the data into Supabase via our remote-helper. |
67 | | -2. **Persist metadata + packs.** During `git push --mirror`, the daemon writes refs/commits/file_changes rows into Supabase tables and uploads each pack file to the Supabase Storage bucket (`git-packs`). Only metadata lands in `public.objects`; the raw pack bytes live in storage. |
68 | | -3. **PowerSync replication.** The PowerSync service streams those tables down to every connected explorer instance. The browser uses `@powersync/web` + TanStack DB collections to reactively query refs, commits, file changes, and the lightweight pack metadata. |
69 | | -4. **File tree & viewer.** When the explorer receives the first pack row for a repo, `gitStore.indexPacks` downloads the pack via the daemon’s signed URL endpoint, indexes it inside the browser’s virtual FS, and marks the referenced commit as “ready.” The file tree then renders real Git entries while the viewer can read blobs directly from the locally indexed pack. |
70 | | -5. **Commit explorer.** The commit view queries the replicated commits/refs table via `@tanstack/powersync-db-collection` and renders filters, diffs, and history without any additional backend calls. |
| 81 | +## Docs |
71 | 82 |
|
72 | | -This flow means that after the initial clone/push, all navigation (branch switching, file viewing, commit diffing) happens entirely locally with the data mirrored inside PowerSync. |
| 83 | +- `docs/supabase.md` – local stack, Edge Function + Actions import, production checklist. |
| 84 | +- `docs/profiles/remote.example.md` – profile setup and remote URL conventions. |
| 85 | +- `packages/cli/README.md` – CLI usage (`powergit login`, `powergit remote add`, etc.). |
0 commit comments