| 1 | # kepler |
| 2 | |
| 3 | Read-only web view for on-disk git repositories. Drop-in compatible with |
| 4 | softserve's `<data>/repos` layout — point `KEPLER_REPO_ROOT` at it. |
| 5 | |
| 6 | ## Features |
| 7 | |
| 8 | - Repo index with description + last-commit time |
| 9 | - README rendering (goldmark) |
| 10 | - Tree / blob browsing at any ref (branch, tag, SHA) |
| 11 | - Syntax-highlighted source view (chroma) |
| 12 | - Raw file download |
| 13 | - Commit log with pagination |
| 14 | - Single-commit diff view |
| 15 | - Branches + tags page |
| 16 | - Archive download: `.tar.gz`, `.zip` |
| 17 | - Atom feed per repo |
| 18 | - Public read-only JSON API |
| 19 | |
| 20 | ## API |
| 21 | |
| 22 | `GET /api/repos` → JSON list of all repos (no auth, CORS `*`): |
| 23 | |
| 24 | ```json |
| 25 | { |
| 26 | "site": "kepler", |
| 27 | "repos": [ |
| 28 | { |
| 29 | "name": "andromeda", |
| 30 | "description": "monorepo", |
| 31 | "default_ref": "main", |
| 32 | "last_commit": "2026-06-14T10:00:00Z", |
| 33 | "url": "https://git.example.com/andromeda", |
| 34 | "atom_url": "https://git.example.com/andromeda/atom.xml", |
| 35 | "clone_https": "https://git.example.com/andromeda.git", |
| 36 | "clone_ssh": "git@git.example.com:andromeda.git" |
| 37 | } |
| 38 | ] |
| 39 | } |
| 40 | ``` |
| 41 | |
| 42 | `url` / `atom_url` use the request host (honors `X-Forwarded-Proto`); clone |
| 43 | fields appear only when `KEPLER_CLONE_BASE_URL` / `KEPLER_CLONE_SSH_HOST` are set. |
| 44 | |
| 45 | ## Run |
| 46 | |
| 47 | ```bash |
| 48 | KEPLER_REPO_ROOT=~/.local/share/soft-serve/repos go run . |
| 49 | ``` |
| 50 | |
| 51 | Then open <http://127.0.0.1:4747>. |
| 52 | |
| 53 | ## Env |
| 54 | |
| 55 | | Variable | Default | Notes | |
| 56 | |---|---|---| |
| 57 | | `HOST` | `127.0.0.1` | use `0.0.0.0` in Docker | |
| 58 | | `PORT` | `4747` | | |
| 59 | | `KEPLER_REPO_ROOT` | `./repos` | dir of bare repos (`*.git/`) or normal repos | |
| 60 | | `KEPLER_SITE_NAME` | `kepler` | shown in header + feed | |
| 61 | | `KEPLER_BASE_URL` | `http://localhost:4747` | public URL for Open Graph / social meta tags | |
| 62 | | `KEPLER_CLONE_BASE_URL` | _(empty)_ | HTTPS entry in the repo-home Clone menu; URL = `<base>/<repo>.git`. Point at the host that actually serves git (e.g. softserve), not kepler | |
| 63 | | `KEPLER_CLONE_SSH_HOST` | _(empty)_ | SSH (scp-style) entry in the Clone menu; URL = `<user@host>:<repo>.git`, e.g. `git@git.example.com`. Include the user | |
| 64 | |
| 65 | The repo-home **Clone** dropdown shows whichever of the two are set; if both |
| 66 | are empty the button is hidden. |
| 67 | |
| 68 | ## Repo discovery |
| 69 | |
| 70 | Each entry of `KEPLER_REPO_ROOT` is treated as a candidate: |
| 71 | |
| 72 | - `<name>.git/` → bare repo; display name = stripped basename. |
| 73 | - `<name>/.git/` → non-bare repo; display name = dirname. |
| 74 | |
| 75 | `description` file in the repo directory shows on the index and repo home |
| 76 | (softserve writes this; the default placeholder is filtered out). |