koh

@june

Version control designed for the solo developer. You can learn it in five minutes. Every koh save is a complete snapshot of your project. Every file. Reversible with one command. Two lanes: dev to experiment freely, main to ship. Extraordinarily fast.

https://koh.asha.software

ZigShellC

1.29.25 · 323 saves · 26,594 lines · updated 3 days ago · trusted

323 saves
107 files ⇓ bundle
323 saves
254fa637b807fix: Repair history pager rendering and resize bounds (v1.29.25)dev3 days ago
a769ba79fb5dadd language-agnostic binary detection to kepr.build generationdev1 week ago
26dc27733f4efill history TUI separator to full slot widthdev2 weeks ago
e6fbe58638f1fix: history TUI frame fills screen + items grouped with separators + tab-bar gap + SELECTED removed The duplicate hint bar came from term.rows() returning ws.row - 3 for safety, leaving the frame 3 rows short of the actual screen. After any terminal-state shift the previous taller frame's statusbar survived on screen below the new shorter frame's statusbar, stacking two hint bars. term.screenRows() returns ws.row raw; the new render emits exactly screenRows lines per frame (1 topbar + 1 tab-gap + screenRows-3 content + 1 statusbar), with \x1b[2K on every line and \x1b[H at start, so a previous frame can never leave remnants regardless of size. buildListLines now distributes slots evenly across the body. Each slot has equal height (off by at most 1) with the same internal structure: top filler, header, message, meta-or-blank, separator, bottom filler. A muted ─-rule separator renders at the bottom of every slot — selected or empty — so six items read as six distinct blocks. The third line of a non-selected slot is no longer blank-on-blank: it's a real separator and the slot total stays consistent regardless of selection. Layout reserves 1 row for the topbar, 1 for the tab-bar gap, 1 for the statusbar; content = screenRows - 3. Tab-bar gap is a single cleared blank line between the topbar and the first slot, giving the chrome above breathing room before items begin. Selected state is shown only by the prefix (▸/◉/·), color contrast, and the meta line on the selected item. The literal 'SELECTED' label is gone from both buildSelectedHeader and buildDetailTitle.dev2 weeks ago
details

Koh

Version control for the solo developer.

Koh is a single binary. No staging area. No remotes. No merge conflicts between people. Just save, undo, and promote — built around how one developer actually works.


Two lanes. One rule.

dev is your scratch pad. main is the official record. Save freely on dev, promote what's good to main. That's the entire branching model.

koh save "add argon2id key derivation"
koh promote

Every save is a complete snapshot

Koh uses a content-addressed object store. Unchanged files between saves cost zero storage. Everything is Blake3-hashed and zlib-compressed. The manifest is the source of truth — the database is a rebuildable index.

If you lose the database: koh recover. It rebuilds from manifests. Nothing is lost.


Safety is the default

Every destructive command shows a preview and prompts for confirmation. The default answer is always N. Pressing enter without reading is always safe.

koh undo rolls back saves. koh discard restores the working tree. koh peek reads a historical snapshot into a temporary directory without touching HEAD. koh load --checkpoint returns you to the last known-good state before a risky session.


Built for agents

koh checkpoint "before opus refactor"
koh save --agent "claude-opus-4" --session "auth refactor" "extract token validation"
koh undo --session

Sessions group related saves. Checkpoints mark safe rollback points. --json output on every read command. Koh maintains LOG.md automatically — every save, checkpoint, tag, and promotion is recorded. Agents open it and immediately know the project's recent history.


The numbers

| | | |---|---| | Commands | 38 | | Source | ~9,300 lines of Zig | | Test suite | 218 cases across 12 suites | | Dependencies | none — single statically-linked binary | | Storage format | Blake3 + zlib · JSON manifests · SQLite index |


Install

curl -fsSL https://koh.asha.software/install.sh | sh

Self-update

koh update

Koh updates itself from Kepr. Checksums verified. Atomic install.


koh.asha.software · Asha Software · MIT