Files
lodge/README.md
T

54 lines
4.6 KiB
Markdown

# lodge
sync for files not meant to be in git
```sh
make env # .env and docker-compose.override.yml from the examples
make recreate # the services in COMPOSE_PROFILES
make check
```
Parts: `backend/`, `frontend/`, each with its own Makefile.
## How it works
`backend/` is one Go module with two binaries. `lodge-server` stores everything in a single SQLite file under `backend/storage/`, serves the API, the built frontend from `frontend/build` and the client binaries it was built together with, so a client always matches its server. `lodge` is the client: a CLI and a daemon in one.
A repository is identified by the hash of its root commit, so nothing is registered by hand. Files are content-addressed blobs; history is a log of revisions, each carrying the branch and the commit of the main repository at that moment. Every repository has a `shared` space and one space per branch. Which path goes where is set in `.lodge` at the repository root, which is synced like any other file:
```
shared docs/agents
shared CLAUDE.local.md
branch .agent
ignore vault/.obsidian/workspace*.json
ignore .DS_Store
```
`ignore` keeps matching files on the machine that has them: they are never pushed, pulled or watched. Its pattern is a glob over the whole path, or over any single name when it has no slash. Synced paths are hidden through `.git/info/exclude`; `.gitignore` is never touched, and files tracked by git are never synced. When two machines edit the same file, the later edit wins and the other version stays in history.
## Adding a machine
Set `ADMIN_TOKEN` in `.env`, sign in to the admin with it, open Machines and press "Connect a machine". The same one-time install command, valid for ten minutes, is available without a browser:
```sh
curl -X POST -H "Authorization: Bearer $ADMIN_TOKEN" https://lodge.example.com/api/codes
```
Running the returned `curl ... | sh` on a Mac or a Linux machine downloads the client, logs it in, starts the daemon under launchd or systemd, installs a `post-checkout` hook through `init.templateDir` so that fresh clones receive their files, and drops a skill for coding agents into `~/.claude/skills` and `~/.agents/skills`. Repositories cloned before that are picked up with `lodge add`. Where no daemon can run, set `LODGE_URL` and `LODGE_TOKEN` and call `lodge sync`.
`make -C backend dev` runs the server without Docker, `make -C backend client` builds the client into `backend/bin`.
## Several servers
A repository can live on another lodge server than the rest of the machine, for example a team's server during an event, while everything else stays on the personal one. Inside the repository, `lodge remote <url> <code>` claims a code from that server and binds the repository to it; further repositories on the same server need only `lodge remote <url>`. Outside a repository the same command only stores the server's token. The binding belongs to the repository key, so worktrees and later clones follow it, and the daemon listens to every server it holds a token for. `lodge remote` prints the server of the current repository, `lodge remote --default` sends it back to the default one. `lodge login` and `lodge update` only touch the default server, and a machine with no default server at all syncs just the repositories bound with `lodge remote`.
On a machine that is logged in elsewhere, the code's `remote_command`, `curl -fsSL https://lodge.example.com/i/<code>/remote | sh`, installs or updates the client, connects the machine to that server without touching the default one, restarts a running daemon so it runs the new binary, and installs the daemon only if it is not there yet. Repositories are then bound with `lodge remote <url>`. Keep the servers a machine talks to on the same version: an older client ignores bindings and syncs every repository with the default server, and `lodge update` brings the default server's client.
Where no service manager runs, in a container for example, `lodge install` says so and leaves it to `lodge daemon &`.
## The admin
The server serves the admin from `frontend/build`. History is drawn as a borehole log: every revision is a bed, newest on top, hatched by the machine that wrote it and labelled with the branch and commit of the main repository. Dragging along the column, or the arrow keys, shows the notes as they were at that revision, and every depth, file and view is a link. A file can be compared with its previous version and put back on the surface; a repository can be deleted with its history, which leaves the files on the machines alone. Machines are listed with their hatch and can be revoked.
`make -C frontend dev` runs the admin against a server on `localhost:8080`.