The HTML coding generator where every prompt is a git commit
Most HTML coding generators give you a textarea and a download button. mk0r runs a real git repo inside the VM that builds your page, commits after every chat turn, and exposes undo, redo, and jump-to-version as real git operations. Here is exactly how the pipeline is wired, with file and line references so you can check.
The problem with most HTML coding generators
Type a prompt, get a page. Type another prompt, get a different page. If turn 5 was the good one, and turn 7 broke the layout, you are scrolling back through chat trying to paste the old snippet into a new session. The generator treats your conversation as stateless noise around a stateful artifact it refuses to version.
mk0r flips that. The artifact is a git repo. Every turn is a commit. Turn 7 is broken? Undo. Turn 5 was gold? Jump back to that SHA. Your history is a real graph, not a chat transcript.
Where the repo comes from
First boot of a session runs initGitRepo in src/core/freestyle.ts (around line 1380). Inside the VM, at /app, it executes this sequence:
That initial SHA is pushed onto the session's historyStack as the anchor, and activeIndex is set to 0. Everything after is relative to this commit.
The per-turn commit (the uncopyable part)
After the agent finishes streaming a turn, the chat route (src/app/api/chat/route.ts around line 388) runs:
The commit message is literally the first line of your prompt. The shell side (commitTurn in freestyle.ts) runs:
If the turn touched no files, the shell prints NOCHANGE and no commit is made. If it did touch files, you get a real SHA back as a version event over the NDJSON stream, and it is appended to historyStack.
Generate, commit, undo, redo
Every chat turn on mk0r is a real commit on a real repo. No login, no credit card, no git knowledge required.
Open mk0r →Undo, redo, and the branching rule
undoTurn and redoTurn both defer to revertToSha, which looks like this:
Undo does not rewrite history, it appends a new commit whose tree matches the target. That means your remote never force-pushes over old work; every state you ever saw is recoverable.
The branching rule is in commitTurn: if you prompt a new turn after an undo, the stack is sliced to activeIndex + 1 before the new SHA is pushed, which matches how any serious editor handles history branching. A new edit from a rewound state forks a new line, and the dropped tail stays reachable on the remote via reflog and the prior SHAs.
Jump to any SHA
jumpToSha(sessionKey, targetSha) is exported alongside undo and redo. It replays the target tree through revertToSha and updates activeIndex to that position, so a subsequent undo walks backward from the chosen point. The UI exposes it through POST /api/chat/revert.
In practice: turn 9 broke the page. You scroll the version list, click the SHA from turn 5, keep iterating from there. Turns 6–9 are not gone, they are just behind you in the history graph.
What this buys you as a generator
Three things other HTML coding generators cannot give you:
- A real diff. Every turn has a before and an after tree. When the agent says "I updated the hero," you can verify which files actually moved.
- Non-destructive rollback. Undo is a commit, not a rewrite. You never lose a version you liked.
- An escape hatch. The repo is pushed to an origin remote. If you outgrow the chat, you clone it and keep going locally.
The spine of a generator is its memory. Most generators have none. mk0r has a git graph.
When this is the wrong tool
If you want one snippet to paste into a blog post and never touch again, a git-backed generator is overbuilt. Grab a snippet site and move on. mk0r earns its complexity the moment you want to iterate more than twice on the same page without losing the version that was working.
Frequently asked questions
Where does mk0r actually commit my generated HTML?
Inside a Freestyle VM, at /app, on a real git repo with an origin remote. The init script (src/core/freestyle.ts around line 1380) runs 'git init', configures user agent@mk0r.com, adds a remote, makes an initial empty commit, and force-pushes to main. After that, every chat turn is a real commit on that branch.
What triggers a commit?
The chat route. Look at src/app/api/chat/route.ts around line 388: after the agent's turn finishes streaming, the server calls commitTurn(sessionKey, msg). The commit message is the first line of your prompt, trimmed and sliced to 120 characters. If the turn produced no file changes, the commit is skipped (the shell prints NOCHANGE and exits).
What does the commit script actually run?
Verbatim, from commitTurn in src/core/freestyle.ts: set -e; cd /app; git add -A; if git diff --cached --quiet; then echo NOCHANGE; exit 0; fi; git commit -q -m '<your prompt>'; git push -q origin main; git rev-parse HEAD. The returned SHA is streamed back to the UI as a 'version' event.
How does undo work?
The session keeps a historyStack of SHAs and an activeIndex. undoTurn decrements the index and calls revertToSha on the previous SHA. revertToSha runs 'git checkout <sha> -- .', stages everything, and commits with --allow-empty so the undo itself is a new commit. You never lose history, you just append a revert on top.
Can I jump to an arbitrary past version?
Yes. jumpToSha(sessionKey, targetSha) is exported from the same file. It replays the target tree via revertToSha and updates activeIndex to that point in the stack, so a subsequent undo walks back from there. The UI exposes this through the POST /api/chat/revert route.
What happens if I edit after an undo, does that wipe my redo?
Yes, by design. commitTurn checks if activeIndex is not at the tip and slices historyStack down to activeIndex + 1 before pushing the new SHA. That matches how editors model branching history: a new edit from a rewound state forks a new line and drops the dead end.
Does the repo survive past the session?
The Freestyle VM is ephemeral, but the git remote is persisted per session. initGitRepo records a repoId on the session, persistSession writes it to Firestore, and every commitTurn pushes to origin. So the generated HTML history lives on the remote, not just in the VM filesystem.
Do I need a GitHub account or signup to get this?
No. mk0r creates the VM, the repo, the commits, and the history for you, no login required. Type a description on mk0r.com and the first turn also creates your first real commit in a brand new repo.
Why version the HTML at all, this is a generator?
Because generators lie. The agent tells you it changed the hero, actually it changed the nav. With a per-turn commit you can 'git diff HEAD~1' against the rendered output and see exactly which lines moved. And when a prompt makes the page worse, undo is a one-click 'git checkout <prev> -- .', not a retype.
Generate HTML with a real commit per turn. Undo, redo, jump back to any version. No signup, no card.
Try mk0r