Onset: version control where nobody waits and nothing gets lost. The on command, its core and onset-server.
| 4 |
| 5 | ## How it works |
| 6 |
| 7 | - **Your work is a change.** A change has an ID made of letters (`rtnbkcvx`; the first 4 or more letters are enough). It saves itself: every `on` command saves first, and edits are saved within seconds. There's no staging and no commit. |
| 8 | - **main is the shared line.** It moves in numbered versions (main 48213). Numbers are always versions and letters are always changes. |
| 9 | - **`on land` puts your change on main.** The server merges it with whatever landed since you started, so don't pull, sync or rebase first. |
| 10 | - **A workspace is a folder working on one change.** Use one workspace per task, and never edit files in a folder another agent is using. |
| 11 |
| 12 | ## The loop |
| 13 |
| 14 | 1. `on status` shows where you are. |
| 15 | 2. Edit files. |
| 16 | 3. `on land -m "Title" -m "Why: … Checked: …"` lands the change. Afterwards you're on a new, empty change and your files are unchanged. |
| 17 |
| 18 | Every command ends with a `next:` line. When unsure, do what it says. |
| 19 |
| 20 | ## When land doesn't go through |
| 21 |
| 22 | Read the exit code or `error.code`: |
| 23 |
| 24 | | Exit | Code | Do this | |
| 25 | |---|---|---| |
| 26 | | 3 | `conflict` | Run `on sync`. Fix every file it lists by removing the `<<<<<<<` / `=======` / `>>>>>>>` markers and keeping the right code, then `on land` again. A file marked `(duplicate)` means main and your change each declared the same thing (two functions with one name, one key twice): keep one. | |
| 27 | | 4 | `checks_failed` | A check failed: one of `onset.toml`'s `[land] run` commands (its output is above). Fix the problem, then `on land` again. | |
| 28 | | 5 | `waiting` | A person has to land or approve it, or it's in review (a change request link is printed; it lands once its approvals and checks pass). Tell the user and stop. Don't retry in a loop. | |
| 29 | | 8 | `secret` | Remove the secret from that line. Real secrets go in `.env`, which only the user can see. Never pass `--allow-secrets` unless the user tells you to. | |
| 30 | | 6 | `offline` | Your change is saved. Try `on land` again later. Landing again is always safe: if the first one went through, it says so and nothing lands twice. | |
| 31 | | 1 | `empty_change` | main already has everything your change does (someone landed the same thing). `on drop` it. | |
| 32 | | 2 | `no_description` | Add `-m "Title"` and run it again. | |
| 33 |
| 34 | ## Working in parallel |
| 35 |
| 36 | - **A separate task:** `on get <project> <new-folder>`, then work only in that folder. From inside a workspace, `on workspaces add <new-folder>` does the same without naming the project. |
| 37 | - **Handing part of your work to a subagent:** `on workspaces add <new-folder> --on .` makes a workspace on a new change that starts from yours as it is now. The subagent works and lands only there; landing it lands your change first. |
| 38 | - **Cleaning up:** `on workspaces` lists this project's workspaces on the machine. `on workspaces clean` removes the ones whose work is done: each is saved first, and goes only if its change is then empty, no `on` command is running in it and nothing in it changed for 2 hours (`--idle 10m` for less). Work that hasn't landed is never removed. |
| 39 | - **Another task in the same folder:** `on new "Title"`. The current change stays saved, and `on switch <id>` goes back to it. |
| 40 | - **Building on a change that hasn't landed:** `on new "Title" --on <id>`. Landing the new change lands both, in order. |
| 41 | - **Picking up a change from another machine or agent:** `on get <project> <folder> --change <id>`, or `on switch <id>` in a workspace you already have. |
| 42 | - **Changes in two projects that must land together** (an API and its client): `on land -m "Title" --with ../other-workspace`. Both land, or neither does. Give the other workspace's change a description first (`on -C ../other-workspace describe "Title"`). |
| 43 | - **Landing later:** `on land -m "Title" --at "fri 9:00"` (or `"in 2h"`). Only when the user asks for a time. |
| 44 | - **A big project:** `on get <project> <folder> --lazy` (Linux, macOS and Windows) shows every file at once and fetches each one the first time it's opened. Work there as in any workspace. If the folder looks empty after a restart (on Windows: files you hadn't opened yet won't open), `on mount <folder>` (or any `on` command run in it) brings it back. On Windows, Git Bash's `mv` can't move a file that hasn't been opened yet (it can't move OneDrive's either; a folder of them moves fine); `cmd /c move`, PowerShell's `Move-Item` or Explorer can. |
| 45 |
| 46 | ## Release lines |
| 47 |
| 48 | - `on line` lists the project's release lines (like `1.x`, kept next to main). Start one only when the user asks: `on line 1.x --from v1.0`. |
| 49 | - **A fix for a line:** `on get <project> <folder> --line 1.x` (or `on new "Title" --line 1.x`), edit, `on land`: it lands on 1.x. |
| 50 | - **A fix that landed on main, for a line too:** `on land <change> --to 1.x`. If it conflicts there, you're put on a new change on 1.x with the conflicts marked: fix them, then `on land`. |
| 51 | - `on log --line 1.x` shows a line's versions; `1.x/3` names its version 3 wherever a version goes (`on show <file> --from 1.x/3`). |
| 52 |
| 53 | ## Looking around |
| 54 |
| 55 | - `on diff` shows what your change changes (`--stat` for a summary). |
| 56 | - `on log` shows recent versions of main. `on log --changes` shows open changes and who has them. |
| 57 | - `on log <path>` shows the versions that changed a file or folder, following it back through moves. `on blame <file>` shows which version last changed each line. `on show <file> --from <version>` prints a file as it was. |
| 58 | - `on status <id>` shows any change, including whether it landed. |
| 59 | - **Finding what broke something:** `on bisect <good-version> <bad-version> --run "<test command>"` tries versions in a folder of its own (your files don't change) and prints the first bad one. The command exits 0 for good, 125 to skip a version it can't judge, anything else for bad. |
| 60 | - `on verify [version]` says who signed the land that made a version (exit 1 if it wasn't signed or doesn't check out). |
| 61 |
| 62 | ## Starting a project |
| 63 |
| 64 | - `on init <folder>` starts a new project that lives only on this machine. Landing works locally. |
| 65 | - `on publish upstream.codes/<owner>/<name>` puts a local project on the host, keeping its history. |
| 66 | - `on import <git-url> --to upstream.codes/<owner>/<name>` makes a project from a git or GitHub repository, with its history. |
| 67 | - `on import <git-url> --change <branch>` brings a git branch into this workspace's project as a change, ready for `on land`. |
| 68 | - `on git` shows the git URL the project clones from. |
| 69 | - If a command says you're not signed in (exit 7), tell the user to run `on login`. Agents get an `ONSET_TOKEN` from the user and never ask for passwords. |
| 70 |
| 71 | ## Sharing and access |
| 72 |
| 73 | Only run these when the user asks. |
| 74 | - `on access <path> @person` makes a folder or file visible only to that person (`@group` for one of the project's groups, `me` for only the user). |
| 75 | - `on access <folder> @person --sealed` also encrypts it on their machines, so the host can't read it. A sealed file that conflicts is merged by `on sync`, not the host. |
| 76 | - `on approve <change>` approves someone else's change. If it was the last approval the project needs, it lands. |
| 77 | - `on access <change> @person` lets someone see your change. Add `--edit` to let them work on it. |
| 78 | - `on access <path or change>` with no names shows who can see it. |
| 79 |
| 80 | ## Fixing mistakes |
| 81 |
| 82 | - `on undo` undoes the last `on` command in this workspace. Run it again to go further back. |
| 83 | - It also undoes a land: main gets a new version that takes it back out, and the change reopens here. |
| 84 | - `on undo <version>` takes an older landed version back out of main without undoing anything else. |
| 85 | - `on restore <file>` puts a file back to how it was before your change. |
| 86 | - `--at "10 min ago"` brings back an earlier save of your own work. `on log --saves` lists the saves, and `--from <change>:<save>` takes the file from one of them. |
| 87 | - `--from <version>` takes the file from a version of main. |
| 88 | - A change taken back out of main reopens, so nothing is lost. `on log --changes` lists it; `on drop <change>` if it's not wanted. |
| 89 | - `on drop` abandons the current change. `on undo` brings it back. |
| 90 | - **A secret or a huge file that landed:** tell the user. Only if they ask, `on purge <path>` shows what taking it out of the whole history would do, and `on purge <path> --yes` does it (owners only; it can't be undone, rewrites the git view's main, and deletes the file here too). A leaked secret still has to be changed. |
| 91 |
| 92 | ## Your session |
| 93 |
| 94 | When you land, your session since your last land (what you were asked, what you said and ran) is kept with the change, secrets removed, for the user only. If the user asks to stop it, run `on sessions off`; to remove what was kept, `on sessions delete --all`. `on sessions show <change>` shows what was kept. |
| 95 |
| 96 | ## Rules |
| 97 |
| 98 | - **Descriptions:** the first line says what changed. Then say why, and what you checked (tests, build). |
| 99 | - Don't land other people's changes, pass `--allow-secrets`, change access, purge, or start release lines unless the user asks. |
| 100 | - Don't print or copy what's in `.env` files. They belong to the user. |
| 101 | - Add `--json` when you want to parse output. It has the same facts, plus `next`. |
| 102 |
| 103 | ## Known limits |
| 104 |
| 105 | - **Git pushes to a project's repository** come into Onset at its next `on` command or read, not by themselves. A fresh workspace can be a few versions behind git main until `on sync` or `on land`, which bring them in. |
| 106 | - **A project's first lazy get** makes its folder snapshot, which takes about a minute for a project of 10,000 files. Every lazy get after that takes a few seconds. |
| 107 | - **Importing a big repository** takes a while: about 25 minutes for 3,000 commits and a gigabyte of files. If it's cut off, `on publish <host/owner/name>` in the import's folder carries on from where the host is (0.9.4 and later; onset-server too). |
| 108 | - **Lands through the HTTP API or MCP** are by the token's account. Only `on land` takes `ONSET_NAME` and `ONSET_EMAIL`. |
| 109 | - **A git push that adds over 32 MB** takes about half a minute to come into Onset; smaller ones take seconds. |
| 110 | - **`on log <file>`** takes tens of milliseconds where git takes a few. |
| 111 |
| 112 | ## git → Onset |
| 113 |
| 114 | | User asks for | Run | |
| 115 | |---|---| |
| 116 | | `git status`, `git diff`, `git log` | `on status`, `on diff`, `on log` | |
| 117 | | `git log -- <file>`, `git blame <file>` | `on log <file>`, `on blame <file>` | |
| 118 | | `git show <rev>:<file>` | `on show <file> --from <version>` | |
| 119 | | pre-commit hooks | `[land] run` in `onset.toml` | |
| 120 | | `git tag v1.0` | `on tag v1.0` | |
| 121 | | `git add`, `git commit` | Nothing: it's saved. Use `on describe "Title"` to set the description. | |
| 122 | | `git push`, "commit and push", "merge to main" | `on land -m "Title"` | |
| 123 | | `git pull`, `git fetch`, `git rebase main` | `on sync` | |
| 124 | | `git checkout -b`, a new branch | `on new "Title"` | |
| 125 | | `git switch`, `git checkout <branch>` | `on switch <change>` | |
| 126 | | `git stash` | `on new` (the current change stays saved) | |
| 127 | | `git checkout -- <file>`, `git restore <file>` | `on restore <file>` | |
| 128 | | `git reset`, `git reflog` to recover | `on undo`, or `on restore <file> --at "<time>"` | |
| 129 | | `git revert` | `on undo` right after landing, or `on undo <version>` for an older one | |
| 130 | | `git bisect` | `on bisect <good> <bad> --run "<command>"` | |
| 131 | | `git cherry-pick` onto a release branch | `on land <change> --to <line>` | |
| 132 | | `git filter-repo` to remove a file | `on purge <file>` (only when the user asks) | |
| 133 | | `git init` | `on init <folder>` | |
| 134 | | `git clone` | `on get <project> <folder>` | |
| 135 | | `git worktree add` | `on get <project> <folder>` | |
| 136 | | open a pull request | `on land` (if you can't land on your own, it asks the people who can) | |
| 137 | | merge a git branch someone pushed | `on import <git-url> --change <branch>`, then `on land` | |
| 138 |