zeon sync
Pull, merge, and push in one command. The mental model, the conflict rules, and the situations you will hit.
zeon sync pulls the latest cloud changes, merges them with your local work, and pushes, in one step.
zeon sync # uses a default commit message
zeon sync -m "Tune gripper offsets"This is the one command to remember. Everything in working-tree commands is for finer control.
zeon syncis what you run day to day.
Mental model
| Term | Meaning |
|---|---|
| Working tree | The folder on your disk holding skills/, workflows/, worlds/, and the rest. |
.zeon/ | Hidden metadata folder that tracks the project. Never edit it by hand. |
| commit | A local snapshot of your working tree. Created by zeon commit, or automatically by zeon sync. Local until you push. |
| HEAD | Your latest local commit. |
| remote head | The cloud commit your local copy last agreed with. zeon status prints it. |
| cloud | The shared copy your teammates and the web app see. |
Run sync from inside a project folder. The CLI finds the project by looking for a .zeon/ directory in the current folder or above it, so there is no project flag to pass and the depth you run from does not matter.
Flags
| Flag | Meaning |
|---|---|
-m, --message <msg> | Message for the commit that records the merge. |
--continue | Finish a sync after you have resolved the conflicts. |
--abort | Cancel an in-progress sync and keep your local changes. |
How zeon sync works
zeon sync works- Checks the cloud. If nothing moved on either side, it prints
already up to dateand stops. - Snapshots uncommitted work. If your working tree is dirty, sync commits it first so nothing can be lost.
- Merges the cloud's files into your working tree, file by file.
- Pushes the result and reports the new commit.
Because it always pulls before it pushes, sync removes the most common failure mode, a zeon push rejected because the cloud moved on. It stops only when the same file changed in both places and the two edits genuinely overlap.
Where
-mlands. The pre-sync snapshot in step 2 always uses the fixed messagelocal changes saved before sync. Your-mmessage goes on the merge commit in step 4. So after a sync that merged cloud changes, expect two commits inzeon log, and only one carries your message.
How a file is merged
For each file, sync compares three versions: the common ancestor, yours, and the cloud's.
| Situation | What sync does |
|---|---|
| Only the cloud changed it | Takes the cloud version (or deletes the file if the cloud deleted it). |
| Only you changed it | Keeps yours. |
| Both changed it, different lines | Merges the two silently. Nothing for you to do. |
| Both changed the same lines | Writes conflict markers into the file and stops. |
| Both changed it and it is binary | Keeps the cloud version, backs yours up, and continues. |
Outcomes of a clean sync
| Situation | Result |
|---|---|
| The merge left your tree identical to the cloud | Fast-forwards, and reports synced with the cloud's sha |
| The cloud had nothing new | Pushes your commits straight up, and reports synced with the pushed sha |
| Both sides changed and merged cleanly | Records a merge commit on top of the cloud tip and pushes it |
You do not need to tell these apart. They all mean it worked. They are listed because the commit count in zeon log differs between them.
Conflicts
When you and the cloud changed the same lines of the same text file, sync writes standard markers into that file, prints CONFLICT <path> for each one, and exits with status 1:
<<<<<<< HEAD
your version
=======
the cloud's version
>>>>>>> remote
HEAD is your side. remote is the cloud's side. Open the file, keep what you want, and delete all three marker lines. Then run zeon sync --continue.
Delete every marker line.
zeon sync --continuerefuses to proceed while any file still contains<<<<<<<,=======, or>>>>>>>, and names the files that need attention. That guard is what stops you committing a half-resolved merge.
During a conflict
| You want to… | Run |
|---|---|
| See which files need attention | zeon status |
| Review what changed | zeon diff |
| Finish after resolving | zeon sync --continue |
| Give up and keep your local work | zeon sync --abort |
--abort is lossless. Because sync committed your uncommitted edits before merging, aborting restores exactly what you had and drops the conflict markers.
If you start a fresh sync while one is in progress, it refuses and tells you to --continue or --abort first.
Binary files
A binary file, a mesh or an .npz for example, cannot be line-merged. When one changed in both places, sync keeps the cloud version in your tree, saves your version under .zeon/backups/<path>, and carries on rather than stopping. It prints a line naming the file and the backup location.
This is not a conflict you have to resolve. The sync completes. But if yours was the version you wanted, copy it back out of the backup and sync again.
Doing it step by step
sync is commit, pull, merge, and push collapsed into one command. The pieces still exist on their own, and there are jobs only they can do.
zeon sync step | Manual equivalent |
|---|---|
| Snapshot uncommitted work | zeon commit -m "…" |
| Fetch and merge the cloud | zeon pull |
| Send the result | zeon push |
Reach for the explicit path when you want to build up several commits locally before sending anything, when you want to read zeon status and zeon diff and decide before anything reaches the cloud, or when you want to commit part of your working tree and leave the rest in progress:
zeon commit -m "Only the skill" skills/my_skill/
zeon commit -m "Two workflows" workflows/pick.json workflows/place.json
zeon push # every local commit goes up togetherWith no paths, zeon commit includes every change: modified, added, and deleted alike. That is the main practical difference from sync, which always takes the whole tree. sync also works on a dirty tree, where pull refuses.
These are not alternatives to
sync. They are what it is made of, and you can move between the two freely. A tree built from three manual commits still ships with a singlezeon sync.
Worked stories
The daily loop
zeon status # see what you changed
zeon diff # review it
zeon sync -m "Adjust waypoints" # merge cloud + push, one stepzeon status groups files as Added, Modified, Deleted, and Unmerged, and prints working tree clean when there is nothing outstanding.
"Someone else pushed while I was editing locally"
Sync. It merges both sides automatically when the edits do not overlap.
zeon sync -m "Local tweaks""The cloud moved and zeon push refused"
zeon push refused"push stops rather than forcing anything, and tells you the cloud has changed since your last sync.
zeon push # refused
zeon sync # reconciles and pushespush only sends. It never merges. sync is what reconciles the two sides. By hand, the same thing is zeon pull, resolve anything conflicting, then zeon push.
"Sync stopped with CONFLICT"
zeon sync
# → CONFLICT workflows/plate_prep.json
zeon status # confirm which files are unmerged
# …edit workflows/plate_prep.json, remove the markers…
zeon sync --continue"I resolved it wrong and want to start over"
zeon sync --abort
# → sync abortedThen fix your files at leisure and run zeon sync again.
"A mesh came back different from what I had"
The sync finished and kept the cloud's copy. If you wanted yours, restore it from the backup and sync again:
cp .zeon/backups/worlds/bench_layout/mesh.npz worlds/bench_layout/mesh.npz
zeon sync -m "Restore local mesh""I am stuck mid-merge and want out entirely"
zeon sync --abort
zeon log # find a commit you trust
zeon reset --hard <sha> # discards uncommitted work, matches that commit
zeon sync
zeon reset --harddiscards uncommitted work. Use it deliberately, and only after--aborthas already given you your pre-sync state back. If you want to look at a past commit instead,zeon checkout <sha>changes only what is on disk, andzeon checkout mainputs you back on the tip.
"I want to see what the cloud has without pushing"
zeon pullpull fetches and merges but never pushes. Its outcomes:
| Situation | What happens |
|---|---|
| Nothing new in the cloud | already up to date |
| Cloud ahead, you have nothing local | Fast-forwards your tree |
| You are ahead, cloud had nothing new | Tells you your local commits are ahead and to run zeon push |
| Both sides moved | Merges. A clean merge is recorded as a merge cloud changes commit. A conflict writes markers and exits 1 |
After resolving a conflict that came from pull rather than sync, finish it with zeon commit -m "merge" and zeon push.
pull refuses to run on a dirty working tree. It names the offending files and tells you to commit, revert, or pass --force.
zeon pull --forcedoes not discard your changes. It pulls despite the dirty tree, three-way merging cloud content into your uncommitted state, so your in-flight edits and the cloud's get interleaved in place. To throw away local work and match the cloud, usezeon reset --hard.
Getting a project onto another machine
zeon clone my-project # creates ./my-project/
cd my-project
zeon syncIf you already have a project folder on disk with no .zeon/ in it, register it instead. The folder must contain skills/, worlds/, and workflows/, and its name becomes the cloud project name:
cd ./my-project
zeon init -m "Import existing project"On the lab machine
Sync before every run, so the workflow you are about to execute on hardware is the latest one:
zeon syncGoing the other way, after capturing a world next to the robot, the explicit path earns its keep. You can check zeon status and confirm you are sending the world snapshot and nothing else before it reaches everyone:
zeon status
zeon commit -m "Snapshot world after re-positioning plates"
zeon pushUpdated 3 days ago