Skip to main content
This article walks through checkpoints — an automatic feature that snapshots your workspace after each tool use in a task. Checkpoints capture incremental changes (file edits, terminal commands, assistant messages), let you inspect diffs, and provide quick rollback options so you can experiment without losing prior work. Checkpoints complement Git. Cline stores snapshots in a shadow Git repository after every tool use, which enables fine-grained comparisons, restores, and replays while leaving your primary Git workflow untouched. You can continue using Git as usual and selectively commit the stable changes you want to keep.
A dark-mode screenshot of a documentation webpage (docs.cline.bot) showing the "Viewing Changes & Restoring" and "Restore Options" sections, with a central content area and navigation menus on the left and right. The page includes an embedded UI mockup for an API request and file restore.
How you interact with checkpoints in the UI
  • Click “Compare” to inspect changes between snapshots.
  • Click “Restore” to reveal options and revert to a previous snapshot.
  • Use the restore variants to restore files only, conversation history, or both.
Typical development flow where checkpoints are helpful:
  1. Create a feature branch.
  2. Ask the assistant to scaffold a web interface for an existing API.
  3. Approve or modify generated files and iterate.
  4. If something breaks, restore the workspace to a previous snapshot and try again.
Quick example: creating a branch and verifying status in the terminal
(venv) jeremy@MACSTUDIO ChevyCastingLookup % git checkout -b feature/web-interface
Switched to a new branch 'feature/web-interface'
(venv) jeremy@MACSTUDIO ChevyCastingLookup % git branch
* feature/web-interface
  main
(venv) jeremy@MACSTUDIO ChevyCastingLookup % git status
On branch feature/web-interface
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
(venv) jeremy@MACSTUDIO ChevyCastingLookup %
Context window: what it contains and why it matters
  • The context window aggregates file contents read by the assistant, terminal commands, prompts, and assistant responses.
  • Everything shown in the UI (colored assistant messages vs. terminal output) contributes to the rolling context.
  • Models have context limits; Cline supports up to ~200K tokens for some models. When you approach that limit, start a fresh conversation or include only the relevant portions of history.
Create directories for the Flask scaffold (example of the command Cline might run):
mkdir -p flask_web_interface/templates flask_web_interface/static/css flask_web_interface/static/js
Representative Flask scaffold code Below are the main files shown so you can see how the pieces fit together. These snippets reflect typical generated files and are safe to inspect or restore from checkpoints.
  • api_client.py — a small API client used by the Flask app:
# api_client.py
import requests
from typing import Dict, Optional
import logging

logger = logging.getLogger(__name__)

class CastingAPIClient:
    """Client for communicating with the FastAPI casting lookup service."""

    def __init__(self, base_url: str = "http://localhost:8000"):
        self.base_url = base_url.rstrip('/')
        self.api_base = f"{self.base_url}/api/casting"
        self.timeout = 10

    def _make_request(self, endpoint: str, params: Optional[Dict] = None) -> Dict:
        """Make a GET request to the API with error handling."""
        url = f"{self.api_base}{endpoint}"
        try:
            response = requests.get(url, params=params, timeout=self.timeout)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as exc:
            logger.exception("API request failed: %s", exc)
            return {}

    def health_check(self) -> Dict:
        return self._make_request("/")

    def search_casting(self, casting_number: str) -> Dict:
        return self._make_request(f"/{casting_number}")
  • templates/casting_detail.html — Jinja template (kept as a code block so template tags are preserved):
{% extends "base.html" %}

{% block title %}{{ casting.casting }} - Chevy Casting Lookup{% endblock %}

{% block content %}
<div class="row">
    <div class="col-lg-8 mx-auto">
        <div class="d-flex justify-content-between align-items-center mb-4">
            <h2>Casting Details</h2>
            <div>
                <a href="javascript:history.back()" class="btn btn-outline-secondary me-2">Back</a>
                <a href="{{ url_for('index') }}" class="btn btn-outline-primary">New Search</a>
            </div>
        </div>

        <div class="card">
            <div class="card-header bg-primary text-white">
                <h3 class="mb-0">
                    <i class="fas fa-cog"></i> Casting Number: {{ casting.casting }}
                </h3>
            </div>
            <div class="card-body">
                <div class="row">
                    <div class="col-md-6">
                        <h5>Basic Information</h5>
                        <p>Production Years: {{ casting.years }}</p>
                        <p>Displacement: {{ casting.displacement }} CID</p>
                        <p>Power: {{ casting.power }}</p>
                    </div>
                    <div class="col-md-6">
                        <h5>Technical</h5>
                        <p>Main Caps: {{ casting.main_caps }}</p>
                        <p>Notes: {{ casting.notes }}</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}
  • app.py — minimal Flask app that uses the API client and serves templates:
# app.py
from flask import Flask, render_template, request, redirect, url_for, flash
from api_client import CastingAPIClient
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__)
app.secret_key = 'change-this-in-production'

api_client = CastingAPIClient()

@app.route('/')
def index():
    """Home page with search form and API status."""
    api_status = api_client.health_check()
    return render_template('index.html', api_status=api_status)

@app.route('/search', methods=['POST'])
def search_casting():
    """Search for a specific casting number."""
    casting_number = request.form.get('casting_number', '').strip()
    if not casting_number:
        flash('Please enter a casting number.', 'warning')
        return redirect(url_for('index'))

    result = api_client.search_casting(casting_number)
    return render_template('results.html', results=result)

if __name__ == '__main__':
    app.run(debug=True, port=5001)
Runtime feedback when Cline generates and runs servers
  • When the FastAPI backend responds, you might see output like:
INFO:     Started server process [25399]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     127.0.0.1:54931 - "GET / HTTP/1.1" 200 OK
{"message":"Welcome to the Casting Number Lookup API","docs":"/docs"}
  • If Flask wants to use a different port (for example when 5000 is occupied), a scaffolded run may display:
🚗 Chevy Casting Lookup Web Interface
Starting Flask development server...
Web interface will be available at: http://localhost:5001
Make sure your FastAPI server is running on port 8000
WARNING:werkzeug: * Debugger is active!
INFO:werkzeug: * Debugger PIN: 118-258-647
With the web app running, you get a simple search UI and an API status indicator.
A webpage titled "Chevy Casting Lookup" with a search box to enter casting numbers, buttons for advanced search and browsing all castings, and an API status indicator.
View results and details directly from the interface.
A screenshot of a "Chevy Casting Lookup" web page showing search results in a table with columns for casting number, years, CID, power range, main caps, and action buttons. The header shows "Found 50 result(s)" and each row has a blue "View Details" button.
Selecting a row opens a detailed view for that casting.
A webpage titled "Chevy Casting Lookup" showing casting details for casting number 3794460. It lists basic info like production years (1968–69), displacement (327 CID), and engine power values (250).
Prompt scope and generated features
  • Because the assistant was given a broad prompt (“create a web interface”), it added convenience features: “browse all”, “search similar”, and filtering by year/power.
  • Narrow prompts yield more deterministic results; broad prompts enable creative additions.
  • If the generated app doesn’t match your intent, restore to a snapshot and re-run with a refined prompt.
Restore options — what you can revert
Restore optionEffect
Restore files onlyReverts project files to the selected snapshot without changing conversation history.
Restore tasks/messagesDeletes messages after the snapshot point (conversation history rolled back), but leaves files as they were at that message.
Restore both files and tasksReverts files and clears the conversation history back to the chosen snapshot.
Common failure example (missing template):
jinja2.exceptions.TemplateNotFound: 404.html
When you encounter errors like this, restoring to the last working snapshot lets you fix prompt instructions or add missing files without redoing unrelated changes. Committing produced files to Git After you’re satisfied with the scaffolded changes, commit them to your branch. Example commit output:
(venv) jeremy@MACSTUDIO ChevyCastingLookup % git add .
(venv) jeremy@MACSTUDIO ChevyCastingLookup % git commit -m "Added Flask Interface"
[feature/web-interface 12796bc] Added Flask Interface
 11 files changed, 1300 insertions(+)
 create mode 100644 flask_web_interface/README.md
 create mode 100644 flask_web_interface/api_client.py
 create mode 100644 flask_web_interface/app.py
 create mode 100644 flask_web_interface/requirements.txt
 create mode 100644 flask_web_interface/run_flask.py
 create mode 100644 flask_web_interface/static/css/style.css
 create mode 100644 flask_web_interface/static/js/main.js
 create mode 100644 flask_web_interface/templates/base.html
 create mode 100644 flask_web_interface/templates/casting_detail.html
 create mode 100644 flask_web_interface/templates/index.html
 create mode 100644 flask_web_interface/templates/results.html
Checkpoints provide fine-grained rollback and experimentation support while preserving your normal Git workflow. Use checkpoints to iterate quickly, then commit to Git when you have a stable, intentional batch of changes.
Summary
  • Checkpoints capture each tool use (file edits, commands, assistant messages) in a shadow repository for quick diffs and restores.
  • They complement — not replace — Git: commit stable snapshots to your main repository as usual.
  • Monitor context window size; when limits are near, start a fresh conversation or trim history.
  • Use checkpoints to experiment with generated code safely, and restore when needed to refine prompts or correct mistakes.
Links and references This workflow reduces risk when working with generative tools and accelerates iterative development by making exploration and recovery fast and straightforward.

Watch Video