When the repository changes
What Kampa does when the token folder in your repository changes without it: a hand edit on GitHub, an amended pull request, another tool's commit. How it notices, what it pauses, and how you bring the change into the project or keep Kampa's value on purpose. Everything here describes what Kampa does today.
The commit Kampa agrees with
Every project connected to a repository records one commit on the base branch: the one Kampa last agreed with the repository on. A push records the commit its branch starts from, on both rails. Connect a repository records the commit it read.
Kampa compares against that commit, not against the branch, so it can tell a change the repository made from a change you made in Kampa.
When Kampa checks
- When you open a project, once, after its tokens load. While the check runs, Checking the repository… shows beside Push to GitHub. You can keep editing.
- Before every push, before any branch exists. This is the check that decides: the one on open only tells you early.
A project with no tokens, or with no GitHub connection, isn't checked. A repository with no base branch, or no token folder on it, has nothing to compare. If the check can't run at all, for example GitHub doesn't answer, it decides nothing on open, and the push runs its own.
How Kampa decides, cheapest first
- Nothing moved. The base branch still points at the recorded commit.
- The token folder is the same. The branch moved, but the token folder at its current commit is identical to the one at the recorded commit.
- The repository already holds what Kampa would write, byte for byte: for example Kampa's own pull request, merged as it was.
- Otherwise Kampa reads the token folder at the branch's current commit, and at the recorded one when it has one, and compares them with the project, token by token.
When the branch moved and any step finds nothing Kampa lacks, the branch's current commit becomes the one Kampa agrees with. Only step 4 can find a change, and it decides by content: key order, indentation and a newline at the end of a file are not changes.
What counts as one change:
- a token, one path in one mode file: its
$value,$type,$descriptionand$extensionstogether; - a group's own properties (
$type,$description,$deprecated,$extensions,$root), one per group per mode file; - a contrast exemption, per pair, across every mode;
- a mode, from the manifest's mode list;
- a component, its document and its resolver together.
A change the repository made that the project already holds, for example the same value typed in both places, needs nothing.
Generated files are never a change: tokens.css, tokens.ts,
components.css, base.css, the component snippets (components/<name>.html)
and the icon licence (components/LICENSE-icons.txt). An edit to one of them
in the repository is not drift and pauses nothing. The
next push overwrites it with what Kampa generates from the project. To change
what they hold, change the tokens or the component documents.
The paused banner
When the repository changed something the project doesn't have, the editor shows a banner. It counts; it doesn't list:
3 tokens and 1 mode changed in the repository since Kampa last pushed
with Push is paused so it doesn't undo them. A token counts once, however many modes it changed in.
A push while the banner holds is refused before anything is written, and shows the banner again. Closing the banner only hides it. (A project with no recorded commit is told, not paused: see below.)
The banner clears by itself once the project holds everything the repository changed. It comes back if an Undo takes those values out again.
Show details
Show details opens What changed in the repository: one sentence counting the changes, then one line per token, with only the part that differs:
spacing.md in light: the repository has 19px, Kampa has 20px.
A typography token names only its members that differ, such as its
fontSize. Changed components are listed by name. View on GitHub opens
the compare view from the commit Kampa agrees with to the branch's current
commit, or the token folder at that commit when Kampa has no recorded one.
Take the repo's version
Take the repo's version copies every change the repository made into the project. It asks first, with a count:
This replaces 2 values in Kampa with the repository's. It also adds 1 token from the repo. One Undo restores them.
Only what the repository changed is replaced. A token the repository didn't touch keeps its value in Kampa, including an edit you made that hasn't been pushed yet.
It is the banner's only action when nothing conflicts, and the second one when something does.
Resolve
When the same thing changed in Kampa and in the repository, differently, or one side removed it and the other changed it, that is a conflict. Resolve is then the banner's first action. It opens Resolve the repository's changes:
- a count: "2 values changed in Kampa and in the repository. Pick which one to keep for each. 3 other changes from the repository apply as they are.";
- for each conflict, its name (
spacing.md in light), Kampa: with Kampa's value, Repository: with the repository's, and a choice between Keep Kampa's and Take the repository's.
A conflict is picked per token in one mode file, not per file and not per project. Apply stays disabled until every conflict has a pick. Every change only one side made applies as it is.
What happens to the other modes
A pick changes only the mode it names, with two exceptions. A token has to be in every mode, so when one side removed a token and the other changed it:
- The repository removed it, Kampa changed it in some mode: one pick for the token in every mode. Keep Kampa's keeps it everywhere; Take the repository's removes it everywhere.
- Kampa removed it, the repository changed it in some mode: one pick for the token in every mode. Take the repository's brings it back in every mode, each with the repository's value, including the modes the repository didn't touch.
Modes:
- A mode the repository added is always a conflict, because it changes the theme axis of every component. Leaving it out asks first, for example "Leave the contrast mode out?" After Apply, the next push drops it from the manifest and deletes the repository's file for it.
- A mode the repository removed is a conflict when Kampa changed it: keep it with Kampa's edits, or remove it.
A result that couldn't be a project is refused by name, before it applies, for example a token that would be in some modes and not others:
Kampa can't apply this yet. color.brand would be in light but not in dark. Kampa needs every token in every mode, so add it to the repo's dark or remove it in Kampa first.
The same goes for components that nest one another (format 0.4). A result that takes a parent from one side and a child from the other, or a repository change that deletes a child or drops a variant a parent picks, is refused with the parent named, for example:
The components wouldn't fit together after this: Part "cancel" of "component.dialog" nests "component.button", which is no component in this project.
A component document and its resolver still move as one; a parent and its child are two documents, so this check is what keeps them in step.
Undo after Apply
Take the repo's version and Apply are each one edit. Undo puts back what the project held before it, all of it at once; Redo applies it again.
Applying writes nothing to GitHub, and it doesn't move the commit Kampa agrees with. So after an Undo that takes the repository's values out again, the banner comes back and pushing is paused again.
After you resolve
Once every conflict is picked and applied, the banner clears and you can push. The push is judged against the branch commit you resolved against, so a value you kept as Kampa's is pushed over the repository's on purpose. If the branch moved again since then, the push is paused again.
A resolution is forgotten on reload. Kampa keeps it in the open editor only, until the next push. Reload before you push and the check on open asks again: values you took from the repository are in the project and no longer count, and a value you kept as Kampa's is a conflict again. Resolve it again, then push.
What the pull request says when the repository moved
- The repository moved, and the project already has everything in it. The branch starts from the branch's current commit, and the pull request is an ordinary one: only Kampa's changes on top of the repository's.
- You resolved, then pushed. Same: the branch starts from the commit you resolved against, and the diff shows what Kampa writes over it, including any value you kept as Kampa's.
- Nothing to write. When the repository already holds everything the push would write, no branch and no pull request are made. Kampa shows Nothing to push and agrees with the branch's current commit.
- Kampa had no recorded commit. A project that last pushed before Kampa started recording one, or whose recorded commit is gone from the repository, can't tell whose change a difference is. It doesn't pause. The banner reads Kampa has no record of agreeing with this repository yet, with the count and "Pushing replaces them with Kampa's. Take the repo's version to keep them." The push goes ahead, and the pull request has a section Replaced in the repository that lists every repository value it wrote over or removed, one line each, for example "spacing.md in light: the repository had 19px, Kampa writes 20px." That push records its commit, and every push after it is paused before it replaces a change it hasn't read.
A token folder Kampa can't read
If the token folder at the branch's current commit can't be read as a project, for example a token that is in one mode file and not the others, the banner reads Kampa can't read the repository's tokens at the short commit, names the problem, and says "Push is paused. Fix it in the repository, then check again." Check again reruns the check. This pauses the push whether or not Kampa has a recorded commit.
Last written by another Kampa project
When the repository's manifest.json lists components that another Kampa
project pushed, the banner adds: "The repository was last written by another
Kampa project." Two projects pushing to one token folder see each other's
pushes as changes in the repository. Kampa can tell only from component
entries, which record the project that pushed them; a manifest with no
components can't say.
The first push after 29 September
Since 29 September 2026, every file Kampa writes ends with a newline. The first
push from a project after that adds one to each mode file, manifest.json, and
each component document and resolver: a newline-only change in the diff of
each. It happens
once. A newline added by GitHub's own editor is not a change either way.
What Kampa never does
- Pushes over a change on the base branch it hasn't read, once it has a commit it agreed with.
- Takes the repository's version, or applies a pick, without you asking. Both are one edit you can undo.
- Moves the commit it agrees with when you apply. Only a push, or a check that finds nothing missing, moves it.
- Merges inside a token. A token's value, type, description and extensions are one unit: one side's or the other's.