Source control
Two layers. Do not merge them.
Layer 1. Git for the host application
Git ships the Next.js host. That means the TypeScript, API routes, UI, and the
ep binary. The remote is Cursor Origin (origin/main). Production deploys to
Vercel from this repository.
git remote -v # see origin
git pull origin main # update host code
Layer 2. Project trees, which git can clone
Every project with a share link is also a read-only git repository. The share token is the credential. It is the same token the join page uses.
Open a project. Press the menu in the title bar. Choose Copy clone URL. Then run:
git clone https://elasticprojects.com/git/<token>
You get the published tree as a normal git checkout with one commit named after
the project. Run git pull later to fetch the current published state as a new
commit.
What works and what does not, while this is an alpha:
| Capability | Status |
|---|---|
git clone |
Works with any stock git client |
git pull |
Works. Each pull fetches the current published tree |
| History | One commit per clone or pull, not the full publish log |
git push |
Not supported. Publish through the web UI or ep |
| Binary files | The web UI stores and serves the bytes. git clone and ep still carry text only |
Treat the clone URL like the share link it contains. Anyone who has it can read the project. Resetting the share link also invalidates the clone URL.
The ep CLI
ep syncs organization project trees with full pull and publish.
npm run ep demo seed
npm run ep -- pull labs/elastic --dir ./product-tree
npm run ep -- push labs/elastic --dir ./product-tree -m "Notes"
ep does not replace git for the host code. It replaces dumping organization
files on a personal PDS.
Remote mode: any hosted instance is an origin
Pass --remote and --token (or set EP_REMOTE and EP_TOKEN). Then ep
works against a hosted instance instead of the local database. Pull fetches the
signed repo CAR and verifies every commit against the key in the repo DID
document. Publish diffs your directory against the remote records and sends
com.atproto.repo.applyWrites batches.
# Pull a project tree from production
npm run ep -- pull elastic --dir ./tree \
--remote https://elasticprojects.com --token TOKEN
# Publish local changes back, removing remotely deleted paths
npm run ep -- push elastic --dir ./tree --prune \
--remote https://elasticprojects.com --token TOKEN
# See what differs before publishing
npm run ep -- status elastic --dir ./tree \
--remote https://elasticprojects.com --token TOKEN
ep hosts ep
The product workspace (elastic under Elastic Labs) on production holds this
repository's own source tree. ep itself publishes that tree over the protocol.
Clone the workspace with git. Pull it with ep. Or fetch the signed CAR with
any atproto library. You then hold the source of the thing that serves it.
Do not use one as the other
| Mistake | Result |
|---|---|
ep pull into repo root |
Overwrites README.md with product tree README |
Expect git push to update Spaces |
The git endpoint is read-only today. Write over XRPC (com.atproto.repo.putRecord) instead |
Expect ep push to deploy Vercel |
Vercel builds from git, not from labs/elastic |
Host code changes go through git. Organization files go through the web UI,
ep, the XRPC record endpoints, or a read-only git clone.
Where this goes next
The hosted service acts as an origin for ep today. The share token is the
credential. What remains:
- Personal API tokens, so publishes are attributed to a member instead of the organization authority.
- Real publish history behind
git clone, so the log shows who published what and when. git pushmapped to a publish, once auth on the git endpoint exists.
Summary
| Tool | Owns | Remote today |
|---|---|---|
| Git | Application source | Cursor Origin, deployed to Vercel |
| Git clone URL | Read-only view of a project tree | elasticprojects.com/git/<token> |
ep |
Organization project files, pull and publish | Local database, or a hosted instance over XRPC |
| atproto sync | Signed repo of a project tree | See the data server page |