Kite AI
GitHub integration · the architecture
The architecture · one app · one linked repo · Next.js · explicit two-way sync

Build in Kite. Back it with GitHub.
One app, one repo, kept in sync.

This replaces the earlier "two surfaces, webhook-synced" draft with what actually shipped. Kite is an AI website builder: every website is a Kite app that can be linked to a single GitHub repository on one branch (main today). The bridge is the Kite GitHub App — installed on the customer's org with scoped, revocable permissions. Users start three ways — from scratch, import an existing repo, or create a new one — or just type import from <repo> in chat. Kite resolves the repo by name, confirms before it replaces anything, and enforces one hard rule: imports must be Next.js projects. Editing, the live preview, secrets and publishing all live inside the Kite app; the source of truth stays in GitHub. Sync is explicit and two-waySync to GitHub pushes, Pull brings changes back.

Live product This page is the model. Want it backed by real screenshots? The companion walks the actual import flow — three entry doors, the GitHub-App connection, the Next.js-only gate, secrets and two-way sync — captured screen by screen from staging.kite.ai. The product flow →
Gold · The Kite app

Where you build, edit & preview

Each website is a Kite app with Website, Code, Secrets, Content, Analytics & Growth tabs. You edit by chat or directly, see an in-app live preview, and hit Publish. The app is the workspace — no separate preview domain to reason about.

Blue · The linked GitHub repo

The source of truth

The Kite GitHub App links one repository on one branch. Code lives in the customer's own GitHub — e.g. appsmithorg/test_1 on main. Access is scoped to the repos they pick and revocable any time from Integrations or Settings → Repository.

The Kite app
this website
Edit · live preview · Publish, all in-app.
Explicit two-way sync
Sync to GitHub ↑ · Pull ↓ · on main
GitHub repository
appsmithorg/test_1
Branch: main · customer-owned.
The flow · connect → import → edit → sync
Path Kite app GitHub repo Drop-off
CONNECT · 01 — 04 GATE · NEXT.JS ONLY IMPORT + EDIT SYNC · GITHUB 01 · ENTRY Start something new: scratch · import · create — or "import from <repo>" in chat 02 · CONNECT Install the Kite GitHub App · scoped repos & permissions D1 · 20% Platform lead denies install 03 · RESOLVE Name the repo · Kite finds the match appsmithorg/test_1 D2 · — No repo match / wrong repo 04 · CONFIRM Importing replaces the current site — confirm before anything irreversible ◇ THE GATE Is it a Next.js project? YES ↓ import · NO → refused, current site kept — NO → D3 · THE GATE Not a Next.js project 06 · IMPORT Pull repo from main into the Kite app · replace current site ▼ GITHUB REPO appsmithorg/test_1 · main 07 · SECRETS Add required env vars in the Secret vault backend/.env · NAME D4 · 8% Creds withheld by sec 08 · EDIT + LIVE PREVIEW Edit in the Kite app · in-app live preview · Publish ▲ KITE APP edit · preview · publish 09 · SYNC (explicit) Sync to GitHub ↑ pushes · Pull ↓ brings changes in · on main D5 · — Sync / pull conflict ● TERMINUS · APP ⇄ REPO LINKED Live in Kite · in sync with GitHub on main
★ The crux
There is no "move to Kite vs. just raise PRs" fork anymore, and no hidden webhook machinery. The model is simply one Kite app bound to one GitHub repo. Two things carry all the load-bearing risk: the Next.js gate at Station 05 (the one hard stop) and the explicit Sync / Pull at Station 09 (the only place app and repo can diverge). Get the gate's messaging and the push/pull conflict handling right, and everything else is downstream.
The entry · the real "Start something new" menu

Four ways in.

In the live product, one button — Start something new — opens three doors, and a fourth path runs entirely inside the chat. One door needs no GitHub at all; the other three put real code under version control. All four merge back into the single track above. See each one in the product →

1 no-Git path
2 GitHub-UI doors
1 in-chat import
DOOR 1 Start from scratch

"I just want a website"

No idea what Git or GitHub is, and doesn't want to learn. Describes the site in plain language; Kite generates it from nothing. The real menu item: Start from scratch.

Describe site Kite generates it Edit + preview
Joins at 08 · Edit — nothing to connect or import
DOOR 2 Create new in GitHub

New site, on my GitHub

No repository yet, but wants the site to live in their own GitHub from day one. Kite creates a fresh repo, links a website to it, then generates the site.

Connect GitHub App Name + create the repo Generate the site Edit + preview
Joins at 02 · Connect → then 06 · Import
DOOR 3 Import from GitHub

Import my live site

Real codebase already on GitHub, already deployed. Picks the repo from the Import from GitHub picker and Kite imports its code — the path the main track documents end-to-end.

Connect GitHub App Resolve · Next.js gate Import into Kite Edit + preview
Joins at 03 · Resolve — the documented main path
DOOR 4 Import via chat

Just say "import from…"

Already inside a Kite app and types "import from test_1" in the chat. Kite resolves the repo by name, confirms before replacing, and pulls it in — no menus, no forms.

Type "import from …" Kite finds the match Confirm replace Import + preview
Joins at 03 · Resolve → then 05 · Next.js gate
The decisions

Six calls that shape the integration.

The load-bearing choices behind the flow above — each one now visible in the live product, not just on a whiteboard. They define what the integration is, and where its risk lives.

1 link model
1 sync rule
+ a hard gate
Architecture · the model

One app ⇄ one repo + branch

Each website binds to a single repository on one branch (main today), shown under Settings → Repository. No mirrored "kite/*" namespace, no second main — the customer's main is the only main. Change repository or Disconnect at any time.

Architecture · sync

Explicit, not webhook-driven

Sync is user-triggered, both ways: Sync to GitHub pushes the app's edits as commits; Pull brings GitHub changes back in. No background webhook machinery — the user decides when app and repo reconcile, which keeps the mental model simple and the surface area small.

Architecture · the gate

Next.js imports only

The import contract is deliberately narrow: Next.js projects only. Anything else is refused with a plain reason, and the current site is left intact. A narrow, enforced contract is what lets Kite promise a clean import every time.

Architecture · entry

Three doors + in-chat

Start from scratch, Import from GitHub, and Create new in GitHub — plus a conversational import from <repo> path inside any app. All four converge on the same import pipeline, so there's one code path to harden, not four.

Security · access

GitHub App is the credential

Access is the Kite GitHub App installation itself — scoped to the repos the customer picks, revocable from Integrations or Settings. Repo runtime secrets (e.g. NAME) live in the in-app Secret vault (backend/.env), supplied before the site runs — never hard-coded.

Architecture · safety

Resolve, then confirm

Kite auto-resolves a named repo to a concrete match (appsmithorg/test_1) and, because importing replaces the current site, always asks for an explicit Yes first. Destructive steps are never silent.

The exits

Five places where it can stall.

Each red exit on the map maps to a card below. Percentages are pre-data estimates — replace with real values after the first 100 imports. Hover a card to highlight its exit on the chart above.

1 connect · 1 resolve
1 gate · 1 secrets
1 sync
D1 · 20% Station 02 · Connect

Platform lead denies the GitHub App install

The marketer asks for Kite; the VP-Eng or platform team approves the permission scope. The install requests read metadata plus read + write to code, workflows and administration — if that feels broad, they say no on instinct.

Let them pick Only select repositories, not all. Explain each scope in plain English at the install screen, and lead with the fact that access is revocable in one click from Integrations.
D2 · — Station 03 · Resolve

No repo match, or the wrong one

The user names a repo Kite can't see (not granted in the App install) or that resolves ambiguously. Kite can't proceed to import what it can't find — and must not import the wrong repo over the current site.

When zero matches, point straight back to Configure GitHub App to widen access. When more than one matches, list candidates and make the user choose before confirming.
D3 · THE GATE Station 05 · Next.js gate

Not a Next.js project

Imports support Next.js only. Anything else — WordPress, a static site, a non-Next.js app — is refused cleanly: "it is not a Next.js project, and imports here only support Next.js repos." The current site is left untouched and Kite offers to find another repo.

Surface the Next.js requirement at the picker and first chat message, before the user invests. For unsupported stacks, capture the framework as a waitlist signal instead of a dead end.
D4 · 8% Station 07 · Secrets

Credentials withheld by their security team

The imported repo needs runtime env vars (Kite flags them by name, e.g. NAME). The platform team approved the GitHub App but draws a hard line at handing over secrets — especially production ones — so the site can't fully run.

Start with staging-only values in the Secret vault and gate prod secrets behind explicit migration. Longer term, read secrets from the customer's own vault at runtime rather than storing them.
D5 · — Station 09 · Sync

Sync / pull conflict

Because sync is explicit, the app and the repo can drift between actions. A Pull after the team pushed to main, or a Sync to GitHub over diverged history, can conflict — the one place app and repo can genuinely disagree.

Detect divergence before the push, show a clear diff, and offer pull-first. Resolve conflicts with the LLM at this step and always preserve a recoverable snapshot of the app's state.