Fast quicksaves and inspectable AI-assisted landing for Git.
Kite splits version control into two phases:
ktcreates instant[kite] savesnapshots while you are coding.kt landrewrites contiguous Kite saves into reviewable commits.kt publishpushes the rewritten branch when you are ready.kt propens a GitHub pull request for the landed branch withgh.
kt go is optional. It creates and checks out a fresh branch for a new piece of work, or switches to the named branch when it already exists. If you are already on the branch you want, keep using kt, kt land, and kt publish there.
The tool is intentionally opinionated about safety:
- landing only operates on committed Kite saves
- the plan is shown before history is rewritten
- landing is local by default
- every land records a rollback marker for
kt undo
When you are coding, run:
ktBy default, Kite stages everything and creates a snapshot like [kite] save 14:02:37.
If you already staged a deliberate subset yourself, Kite respects that selection and saves only the staged changes. That path is there for exceptions; the normal workflow is still to let Kite capture everything for you.
Quicksaves intentionally skip Git hooks to stay fast. Landed commits use normal git commit behavior, so hooks do run when polished history is written.
When your branch is full of contiguous Kite saves, run:
kt landKite analyzes the diff introduced by those saves, proposes logical commit groups, and only rewrites history after you confirm the plan.
Grouping is hunk-level: when one file contains changes for different purposes, its hunks can land in different commits. The plan marks split files with (1/2 hunks)-style annotations. Before rewriting anything, Kite replays the hunk-level plan against a temporary index and requires the result to reproduce your saved state exactly; if it cannot, it lands whole files instead.
Kite also feeds recent non-Kite commit messages from the current repository into the prompt so landed messages follow the repo's existing style when possible. If the repo does not show a clear pattern, Kite falls back to Conventional Commit style.
Typical landed output looks like:
feat(api): add stripe webhook endpointsfeat(ui): build checkout modal component
If the AI is unavailable, Kite shows the failure and asks for one manual commit message before any history is changed.
Once the branch is landed, run:
kt prKite gathers everything a good pull request needs, drafts it with the same AI as kt land, shows you the result, and only creates it after you confirm. See kt pr below for details.
Ensure you have Rust installed, then build and install the binary globally:
git clone https://github.com/binbandit/kite.git kite
cd kite
cargo install --path .This repo also ships an installable agent skill at skills/use-kite.
Install it from GitHub with the skills CLI:
npx skills add https://github.com/binbandit/kite --skill use-kiteInstall it specifically for Codex:
npx skills add https://github.com/binbandit/kite --skill use-kite -a codexInstall it globally so it is available across projects:
npx skills add https://github.com/binbandit/kite --skill use-kite -a codex -gIf you are testing from a local checkout, install from the current directory instead:
npx skills add . --skill use-kite -a codexCreates and checks out a new flow branch. If the branch already exists locally, Kite switches to it and prints a note that no new branch was created. Use it when you want to start or resume a branch for a piece of work. If you are already on the right branch, skip this command entirely.
kt go does not change how landing works. After it switches branches, you keep working normally with kt, kt land, and kt publish on that branch.
Kite prefers origin/HEAD when it exists, otherwise falls back to main, master, or the current branch.
kt go stripe-webhooksThe zero-friction quicksave. Run this constantly while you work.
- If the worktree is clean, Kite exits without creating a commit.
- If you already staged a deliberate subset, Kite quicksaves only that staged selection.
- Otherwise Kite runs
git add -Aand snapshots tracked plus untracked changes. - Quicksaves use
--no-verify, so hooks stay out of the way while you are in the flow.
ktSynthesizes contiguous Kite quicksaves into a polished local history.
- Requires an existing
HEADcommit. - By default, requires a clean working tree. If you still have WIP changes, run
ktfirst or stash them. - Use
--allow-dirtyto land while your worktree is dirty;kttemporarily stashes and restores those changes. - Only rewrites contiguous
[kite] savecommits at the top of history. - Splits changes by hunk, so one file can contribute to multiple commits. Binary files, mode changes, and renames stay whole.
- Verifies the hunk-level plan against a temporary index first; if the replayed commits would not reproduce your saved state bit-for-bit, Kite falls back to whole-file grouping.
- Shows the proposed commit plan before rewriting anything.
- Stores the pre-land
HEADinrefs/kite/pre_landsokt undocan restore it later. - Creates normal
git commits, so hooks do run during landing. - If landing fails after rewriting starts, Kite keeps the partial state on a
kite-recovery-*branch so partial landed commits or staged changes are not lost. - Lands locally by default. Use
kt publishafterward, or pass--pushto publish immediately after landing.
kt landSkip the confirmation prompt:
kt land --yesLand without a clean worktree:
kt land --allow-dirtyLand and publish in one step:
kt land --pushPublishes the current branch after you review the rewritten local history.
- Pushes with
--set-upstream origin <current-branch> --force-with-lease— and nothing else. - Deliberately no
git pull --rebasefirst: after a land, the remote still holds the old saves, and rebasing onto them would resurrect the history you just rewrote. - If someone else pushed to the branch, the lease rejects the push and Kite reports it; you decide how to reconcile.
- If no remote exists, Kite exits without error and leaves the history local.
kt publishOpens a GitHub pull request for the current branch using the GitHub CLI (gh). It is deliberately smart about the draft:
- Requires
ghto be installed and authenticated, and a remote to exist. - Refuses to run with unlanded saves so the pull request always shows polished commits — run
kt landfirst. - Publishes the branch automatically when the remote is missing it or behind it.
- If a pull request is already open for the branch, Kite pushes any new commits, checks whether the body still reflects the branch, and offers a refreshed body when it doesn't — preserving the existing structure and any human-written notes. Without AI, the existing body is never touched.
- Finds the repository's pull request template in the places GitHub looks (
.github/, the repo root,docs/, and.github/PULL_REQUEST_TEMPLATE/), fills it in, and drops sections that don't apply — no empty headings, noN/A, no leftover boilerplate. - Discovers PR-related agent skills installed on the machine (
.claude/skills,.agents/skills, andskillsin the repo;~/.claude/skills,~/.codex/skills, and~/.agents/skillsper user) and treats them as your own instructions for how the pull request must be written — they take precedence over the default rules. - Uses recent merged pull request titles from the repository as style examples for the new title.
- Drafts the title and body with the same AI as
kt land. Without AI, it falls back to a deterministic draft built from the template and the branch's commits. - Always previews the pull request and asks for confirmation before creating anything.
kt prCreate it as a draft, target a different base branch, or skip the confirmation:
kt pr --draft
kt pr --base release/1.2
kt pr --yesAttempts to restore the pre-land state.
- Requires a clean working tree.
- Hard-resets to
refs/kite/pre_landand force-pushes if a remote exists. - Deletes the rollback marker after a successful undo so you do not accidentally replay it twice.
kt undoBoth kt land and kt pr use one AI, reached through the OpenAI Responses API, and fall back without blocking either flow.
- Base URL env precedence:
KITE_OPENAI_URL,KITE_OPENAI_BASE_URL,OPENAI_URL,OPENAI_BASE_URL - Model env precedence:
KITE_OPENAI_MODEL,OPENAI_MODEL - API key env precedence:
KITE_OPENAI_API_KEY,OPENAI_API_KEY,KITE_API_KEY,OPENAI_KEY - Timeout env:
KITE_OPENAI_TIMEOUT_SECS - Default base URL:
https://api.openai.com/v1 - Default model:
gpt-5.4-mini - Default timeout: 120 seconds
- Kite normalizes base URLs that end in
/responses,/chat/completions, or omit/v1
export OPENAI_API_KEY="sk-..."
export KITE_OPENAI_MODEL="gpt-5.4-mini"
export KITE_OPENAI_TIMEOUT_SECS="120"Manual fallback
If the AI is unavailable, Kite shows the failure and keeps working: kt land asks for one manual commit message (leaving it blank aborts without changing history), and kt pr builds a deterministic draft from the template and the branch's commits.
Kite keeps the risky parts explicit:
- Clean-worktree landing by default:
kt landrefuses to run with staged or unstaged WIP, so scratch files do not get swept into a landed commit by surprise. - Dirty worktree override:
kt land --allow-dirtytemporarily stashes uncommitted changes, lands saved commits, then restores those changes. - Preview before rewrite: Kite shows the proposed commit plan before it rewrites history.
- Rollback marker: Every successful land records the previous
HEADatrefs/kite/pre_land. - No dropped changes: If the AI misses hunks, each one joins the commit already touching its file, or lands in a
chore: unclassified updatescommit — never silently omitted. - Exact-tree verification: A hunk-level plan is replayed in a temporary index before any rewrite and must reproduce the pre-land tree exactly, otherwise Kite lands whole files instead.
- Explicit publish: Landing is local by default. Publishing remains a separate step unless you opt into
--push. - Preview before PR:
kt prshows the full title and body and asks for confirmation before anything reaches GitHub.
Built for developers who want cheap quicksaves and cleaner review history.