Working from a checkout
How to work on a LazyFrog project from your own computer with Claude Code: clone it, change it locally, and git push to update the preview.
When the user works on a copy of the code with Claude Code or Codex (on their own machine or in their AI's cloud session), the preview stays the source of truth: it is what runs, what other people's AIs work on and what a publish takes. Work in the checkout; push to update the preview; use the LazyFrog tools to look (logs, database, screenshots) and to publish. The preview and the repository are one history.
- The code and the tools.
git clone https://git.lazyfrog.dev/<project>.git: git asks for a user name (anything) and a password, a personal token the user makes in the portal (Account › Access tokens, "Read and write" to push; you can't make one, and only the project's owner and editors can push). New projects carry.mcp.json, which Claude Code reads (it asks once, then connects LazyFrog's tools), andCLAUDE.mdandAGENTS.mdwith these rules in short. Codex:codex mcp add lazyfrog --url https://mcp.lazyfrog.dev/mcp, thencodex mcp login lazyfrog. An older project may not have the files: offer to add them (.mcp.jsonis{"mcpServers": {"lazyfrog": {"type": "http", "url": "https://mcp.lazyfrog.dev/mcp"}}}). - The remote. In a clone from git.lazyfrog.dev it is
origin; in an export,originorlazyfrog(whenoriginis GitHub). A checkout of the GitHub repository adds it once:git remote add lazyfrog https://git.lazyfrog.dev/<project>.git. Below,lazyfrogmeans whichever names it. - Code that isn't on LazyFrog yet (a repository only on the user's machine; one on GitHub is
project importwith its address instead):project createfrom the template nearest its stack (blankfor most), then in the checkoutgit remote add lazyfrog https://git.lazyfrog.dev/<project>.git,git fetch lazyfrogandgit merge lazyfrog/main --allow-unrelated-histories. The project's starter files (services.json,Dockerfile,compose.yml,migrations/0001_init.sql,CLAUDE.md,.mcp.json…) join the user's history. Where both have a file, keep the user's (public/index.html,README.md) and add LazyFrog's.gitignorelines to theirs. Then make it run here before pushing: pointservices.jsonat the app (dev,build,start, listening on$PORT,healthcheck_path), rewriteDockerfileandcompose.ymlfor its stack, and move its schema intomigrations/, numbered after0001_init.sql; an app with its own migration tool sets it as"migrate"instead (one or the other, never both). Commit, and push. - Push to update the preview. Edit and try it in the checkout as anywhere else (
compose.ymlruns the app with a PostgreSQL of its own and the sameDATABASE_URL;.env.examplenames the variables), commit, thengit push lazyfrog main(the preview's branch). The push answers on git's progress lines (remote: LazyFrog: …): "preview updated: https://p-….lazyfrog.app · build 41 s · 2 migrations applied to preview", or the step that failed with its last lines and what to do. Read them; don't push again unchanged. When the start takes longer than about a minute and a half, the push ends with "still …; the outcome goes on the project's activity": follow withservice_status. - When the push is refused, it says why in its last line (
! [remote rejected] main -> main (…)), and nothing in the preview changed:- "the preview has N commits you don't have": someone (or an AI over the tools) changed the
preview; uncommitted work there was committed first, as "Changes made in the LazyFrog
workspace".
git pull lazyfrog main, resolve any conflicts, push again. Never force: a forced or non-fast-forward push is always refused. - "contains what looks like a secret": the file and line are above it. Take the value out of
those commits (amend or rebase), put it in a secret (
secrets request), and push again. - "another AI is working in this project": its lease (one AI at a time) is held; try again in a minute.
- "over the plan's disk", or a read-only token: say so to the user (the plan, or a "Read and write" token).
- "the preview has N commits you don't have": someone (or an AI over the tools) changed the
preview; uncommitted work there was committed first, as "Changes made in the LazyFrog
workspace".
- Other branches are stored ("stored; the preview follows main"); only the preview's branch changes the preview.
- Schema changes: add
migrations/000N_name.sqlin the checkout and push: pending migrations run on the preview's database as part of the push (a snapshot first), unlessservices.jsonsays"migrate_on_push": false(thendb migratethrough the tools). A publish applies them to the live database after its rehearsal. - Without the push (or to change only a file or two), the tools still work:
fs_writefiles(pathsworkspace/…),gitcommit, thengit pullin the checkout. - Look through the tools:
logs_tail,service_status,http_get,preview_screenshot, anddb_readanddb_schemafor the preview's database (it isn't reachable from the machine). - Never commit secrets (
.env, keys, tokens: ask the owner withsecrets request, and keep local values in an ignored.env),.lazyfrog/, dependencies or build output. - Publishing goes through the tools:
deploy preflight, thendeploy publishwhen the user says so (see Publishing). A push publishes by itself only when the user turnedauto_publishon.
For your AI: this page as Markdown · llms.txt