Agent Skills in Claude Code and Visual Studio Code: Setup, Benefits, Risks, and a Step-by-Step Example

Image
 AI coding assistants are useful for one-off questions, but many development tasks are not one-off tasks. A team may follow the same testing procedure before every release, use a specific format for code reviews, or require certain checks whenever a database migration is created. Repeating those requirements in every prompt is inefficient. Putting all of them into a permanent instruction file is not always ideal either, because the assistant may receive irrelevant information for tasks that do not need it. This is the problem that Agent Skills are designed to solve. A skill packages reusable instructions, supporting files, examples, and optional scripts into a folder. Claude Code or GitHub Copilot in Visual Studio Code can discover that folder and load its contents when the current task matches the skill’s purpose. Both environments support the open Agent Skills format, which makes it possible to share some skills across tools. This guide explains what skills are, how they differ ...

Using Git Checkpoints During AI-Assisted Development



AI coding assistants can change a project much faster than most people can review it.

A single prompt may update a function, modify several files, create tests, adjust configuration, and run commands. When the result works, that speed feels productive. When it fails, the same speed can make it difficult to remember which version was stable.

Git checkpoints solve this problem.

A checkpoint is a known project state that you can identify, review, and return to. In most cases, that checkpoint is a clear Git commit created after a small feature has been tested.

The goal is not to commit every few minutes without thinking. The goal is to create a reliable boundary between verified work and the next AI-generated experiment.

What You Will Learn

By the end of this guide, you should be able to:

  • explain what a Git checkpoint is;
  • decide when a change is ready to become a checkpoint;
  • create focused commits during AI-assisted development;
  • use branches for larger or uncertain experiments;
  • separate verified work from unfinished changes;
  • inspect the difference between checkpoints;
  • return selected files to a committed state;
  • reverse a committed change safely;
  • avoid common checkpoint mistakes;
  • build a practical Git rhythm for the Personal Reading List Tracker.

What Is a Git Checkpoint?

A Git checkpoint is a committed state of the project that you recognize as meaningful and sufficiently verified.

For example:

Create reading list page structure
Add responsive base styles
Render books from application state
Validate book titles
Add book removal
Filter books by reading status

Each commit represents a project state with one clear improvement.

A checkpoint should answer three questions:

What changed?
Why was it changed?
How was it verified?

When those questions have clear answers, the commit can serve as a reliable recovery point.

A checkpoint is more useful than a random backup folder because Git records:

  • which files changed;
  • which lines changed;
  • who created the commit;
  • when it was created;
  • the message describing its purpose;
  • its relationship to earlier commits.

Why AI-Assisted Development Needs More Checkpoints

Traditional coding can also go off track, but AI tools often increase the size and speed of changes.

A developer may ask:

Add localStorage persistence to the reading list.

The AI might:

  • add a storage key;
  • create load and save functions;
  • modify initialization;
  • update Add Book behavior;
  • update Remove behavior;
  • add error handling;
  • change the README.

That may be a reasonable set of changes.

It also creates several places where a bug could appear.

Without a checkpoint before the task, you may not know whether the application was already broken.

Without a checkpoint after the task, the persistence changes may become mixed with the next feature.

A useful sequence is:

Verified checkpoint
→ One AI-assisted task
→ Review
→ Test
→ New checkpoint

This gives every experiment a clear beginning and end.

A Checkpoint Is Not Just “The Code Runs”

A project can run and still be unready for a checkpoint.

Before committing, confirm:

  • the intended feature works;
  • related existing behavior still works;
  • the diff is understood;
  • no unexpected files are present;
  • no secrets are included;
  • debugging output has been removed;
  • the commit has one main purpose.

For example, a filter feature may appear to work while silently changing the stored status values.

The page runs, but the change does not match the project brief.

A checkpoint should represent reviewed work, not merely executable work.

The Basic Checkpoint Workflow

Use this workflow for each feature.

1. Confirm the Current State

Run:

git status

You want to know whether the repository is clean before beginning.

Then review recent commits:

git log --oneline -5

A clean starting point may look like:

2ac7e31 Add book removal
fd81b26 Validate book titles
c5a4d77 Add books through the form

The latest commit is your current checkpoint.

2. Define One Task

For example:

Add status filtering without modifying stored book data.

Record:

  • expected behavior;
  • allowed files;
  • prohibited changes;
  • verification steps.

3. Let the AI Make the Focused Change

Use GitHub Copilot or Claude Code with clear boundaries.

Do not start a second feature before reviewing the first one.

4. Inspect the Result

Run:

git status
git diff

Confirm that the changed files match the task.

5. Test the Feature

For filtering:

- All shows every book.
- Want to Read shows only matching books.
- Reading shows only matching books.
- Finished shows only matching books.
- Changing filters does not delete books.

6. Stage Specific Files

For example:

git add app.js

Then inspect:

git diff --staged

7. Create the Checkpoint

git commit -m "Filter books by reading status"

Now the feature has a clear place in project history.

When Should You Create a Checkpoint?

A checkpoint is useful after a complete, testable unit of work.

Good checkpoint moments include:

  • project structure created;
  • one user-facing feature completed;
  • one bug fixed;
  • one refactor verified;
  • documentation updated to match behavior;
  • a dependency deliberately added and reviewed;
  • deployment configuration tested.

Poor checkpoint moments include:

  • code does not run;
  • the feature is only half connected;
  • several unrelated experiments are mixed together;
  • you do not understand the diff;
  • temporary credentials or logs remain;
  • the AI says it works, but you have not tested it.

A checkpoint should be a place you would feel comfortable returning to later.

Keep Commits Focused

A useful commit has one main purpose.

Good example:

Persist books in local storage

Less useful example:

Update storage, redesign buttons, rename fields, fix README

The second commit contains several unrelated concerns.

Focused commits improve:

  • review;
  • debugging;
  • history;
  • selective reversion;
  • collaboration;
  • future maintenance.

Suppose local storage introduces a bug. If persistence has its own commit, you can inspect or revert that change without removing unrelated styling work.

Match the Commit to the Prompt

A practical AI-assisted workflow aligns four things:

One feature
→ One prompt
→ One review
→ One commit

For example:

Feature

Preserve books after refresh.

Prompt

Add local storage loading and saving without changing the data model.

Review

Check app.js, storage key use, JSON handling, and error recovery.

Commit

Persist books in local storage

This alignment makes the project history easy to understand.

It also helps you notice prompt drift. If the AI changes something that does not belong in the intended commit, separate or remove it.

Example Checkpoint Plan for the Reading List Tracker

The project history might develop like this:

1. Create reading list project structure
2. Add semantic form and list markup
3. Add responsive base styles
4. Render books from application state
5. Add books through the form
6. Validate book titles
7. Add book removal
8. Filter books by reading status
9. Persist books in local storage
10. Improve empty and error states
11. Add core behavior tests
12. Prepare static deployment

Each commit describes one meaningful project step.

A future reader can understand how the application evolved without opening every file.

Use git diff Between Checkpoints

Git can show the difference between two commits.

View a recent commit:

git show <commit-hash>

Compare two checkpoints:

git diff <older-commit> <newer-commit>

For example:

git diff fd81b26 2ac7e31

This can answer:

  • What changed when removal was added?
  • Which functions were modified?
  • Did the data model change?
  • Did HTML or CSS change too?
  • Which commit likely introduced the bug?

This is especially helpful when an AI session starts failing after several successful features.

Use Feature Branches for Riskier Work

A branch creates a separate line of development.

You do not need a new branch for every tiny edit, but branches are useful for:

  • multi-file features;
  • uncertain experiments;
  • API integration;
  • major refactoring;
  • deployment configuration;
  • work that may be abandoned.

Before starting the feature, confirm a clean state:

git status

Create and switch to a branch:

git switch -c feature/local-storage

Now commits are recorded on that branch.

Check:

git branch --show-current

Expected output:

feature/local-storage

You can experiment without immediately changing the main branch.

A Branch Does Not Replace Checkpoints

A branch is a workspace boundary.

Commits are still the checkpoints inside it.

A useful branch history might be:

Add storage load and save helpers
Connect persistence to book creation
Persist book removal
Handle invalid stored JSON

You can review and test the branch before combining it with the main line of development.

A branch containing one enormous unreviewed commit is harder to inspect than a branch with several focused checkpoints.

Merge a Verified Feature Branch

After the feature is tested, return to the main branch:

git switch main

Update it when appropriate:

git pull

Then merge the feature branch:

git merge feature/local-storage

Run the application and test the feature again after merging.

Then check:

git status
git log --oneline --graph -10

Exact collaboration and merge practices vary by project. For a small personal project, the important point is that the branch should be reviewed before its work becomes part of the main development line.

Name Branches Clearly

Useful branch names describe the task:

feature/local-storage
feature/book-filtering
fix/filtered-empty-state
docs/update-readme

Avoid vague names such as:

test
new
changes
ai-work
version-2

A clear name helps you remember the branch’s purpose when several experiments exist.

Use Temporary Stashing Carefully

Sometimes you have unfinished changes but need to switch tasks.

Git can temporarily store tracked working changes:

git stash push -m "unfinished filter experiment"

Check the stash list:

git stash list

Later, restore the most recent stash:

git stash pop

A stash is not the same as a checkpoint.

It is temporary storage for unfinished work.

Stashes can become confusing when many are created without clear names. They are also easier to forget than commits.

Use a stash when:

  • the work is incomplete;
  • you do not want to commit it;
  • you need a temporarily clean working tree;
  • you plan to return soon.

Do not use stashes as long-term project history.

Check Untracked Files

By default, untracked files may not be included in a normal stash.

When untracked files matter, review them before deciding what to do.

Do not assume that a stash captured every file in the repository.

Run:

git status

after stashing to confirm the resulting state.

Checkpoint Before a Risky AI Experiment

Suppose the current project is working and you want an AI agent to refactor app.js.

Before the refactor:

git status

If the working tree is clean, the latest commit is already your checkpoint.

If there are verified changes not yet committed:

git add app.js
git diff --staged
git commit -m "Complete reading status filtering"

Now begin the refactor from a known state.

This gives you a clear comparison:

Before refactor:
Known working commit

After refactor:
Uncommitted AI-generated changes

If the experiment fails, you can discard the uncommitted refactor without losing the verified filtering feature.

Do Not Create “Backup Commits” with Broken Work

Beginners sometimes create a commit with a message such as:

backup before AI fix

even though the working tree contains broken or unexplained code.

That commit is technically a checkpoint, but not a trustworthy one.

A better approach is:

  • commit only verified work;
  • use a branch for uncertain experiments;
  • use a named stash for short-term unfinished work;
  • save a temporary patch when recovery requires it.

A checkpoint should communicate quality and meaning, not merely fear of losing files.

Use a Temporary Patch When the Session Is Unclear

When you need to preserve the exact current diff before restoring files:

git diff > ai-experiment.patch

This saves the uncommitted tracked changes as text.

After restoring the repository, you can inspect the patch in an editor.

This is useful when:

  • the AI session produced mixed changes;
  • you want to preserve evidence;
  • only part of the experiment may be reusable.

A patch file is not a replacement for normal commits.

It is a recovery aid.

Do not publish patches containing credentials or private data.

Restoring a File to the Latest Checkpoint

Suppose the AI modified styles.css, but the task should have changed only app.js.

Review first:

git diff styles.css

If the changes are unwanted:

git restore styles.css

This returns the working file to the current committed version.

Then verify:

git status

The stylesheet should no longer appear as modified.

Remember that uncommitted work in that file is discarded.

Restoring Only Part of a File

When one file contains both valid and unwanted changes:

git restore -p app.js

Git will show sections and let you choose which ones to discard.

This can help when an AI assistant added the requested filter and also refactored unrelated functions.

Interactive operations require careful reading.

Afterward:

git diff app.js

Confirm that the remaining changes are complete and consistent.

Unstaging a File Without Losing the Work

Suppose you staged too much:

git add app.js styles.css

You later decide that the CSS change should not be in this commit.

Unstage it:

git restore --staged styles.css

The CSS changes remain in the working directory, but they are removed from the staged commit.

Check:

git status
git diff --staged
git diff styles.css

This lets you separate one mixed session into focused commits.

Reversing a Committed Checkpoint

Sometimes a committed feature must be undone.

Use:

git revert <commit-hash>

For example:

git revert 4f2a0bc

This creates a new commit that reverses the selected commit.

The original commit remains in history.

This is useful when:

  • the commit has been pushed;
  • other work follows it;
  • you want an explicit record of the reversal;
  • shared history should not be rewritten.

After reverting:

git status
git log --oneline -5

Then test the application.

A revert can produce conflicts when later changes depend heavily on the reverted commit. Review the result carefully.

Avoid Destructive Recovery as a First Choice

Commands that rewrite history or discard the working tree can remove valuable work.

Do not use commands such as a hard reset casually because an AI assistant suggested them.

Prefer:

  • git status;
  • git diff;
  • targeted git restore;
  • git restore --staged;
  • a feature branch;
  • a named stash;
  • git revert.

The safest recovery method is usually the most specific method that solves the problem.

How Often Should You Commit?

There is no fixed time interval.

Commit when a coherent unit of work is:

  • complete enough to describe;
  • reviewed;
  • tested;
  • free from unrelated changes.

For a small app, that may mean several commits in one session.

For a difficult bug, one commit may represent a longer period of investigation.

Do not commit based only on elapsed time.

Commit based on verified meaning.

Do Not Wait Until the End of the Day

A common weak workflow is:

Build several features
→ Fix several bugs
→ Change styles
→ Add storage
→ Make one final commit

That commit hides the project’s development path.

If a bug appears, it becomes harder to identify which feature introduced it.

A stronger workflow is:

Add feature
→ Test
→ Commit
→ Add next feature
→ Test
→ Commit

This creates more useful checkpoints and safer experimentation.

Write Commit Messages That Describe Behavior

A good commit message is concise and specific.

Examples:

Create reading list page structure
Add books through the form
Validate empty book titles
Filter books by reading status
Persist books in local storage
Handle invalid saved reading data

Avoid:

Update
Changes
AI work
Fix code
Latest version
Working now

A useful test is:

Could someone understand the purpose without opening the diff?

If not, improve the message.

Review Before Committing

Use this sequence:

git status
git diff
git add app.js
git diff --staged
git commit -m "Filter books by reading status"

Each command answers a different question.

git status

Which files changed?

git diff

What remains unstaged?

git add

Which changes will be considered for the commit?

git diff --staged

What exactly will the commit contain?

git commit

Record the verified checkpoint.

Do not skip the staged review merely because the working diff looked correct earlier.

Add Verification Notes to Your Workflow

Git commit messages are usually concise, but you can keep a small verification note in your task or pull request.

For example:

Feature:
Status filtering

Verified:
- All shows all books.
- Each status shows only matching books.
- Adding a book respects the active filter.
- Removing a book updates the filtered list.
- Filtering does not modify localStorage.

This creates evidence beyond “the AI said it works.”

For a personal project, a short checklist in your development notes may be enough.

Example: Adding Local Storage with Checkpoints

Local storage touches several behaviors, so use a branch.

Create the Branch

git switch -c feature/local-storage

Checkpoint 1: Add Storage Helpers

Implement:

  • one storage key;
  • saveBooks();
  • loadBooks().

Test the functions separately where practical.

Commit:

git add app.js
git diff --staged
git commit -m "Add reading list storage helpers"

Checkpoint 2: Load Books at Startup

Connect loadBooks() to application initialization.

Verify:

  • no saved data produces an empty list;
  • valid saved data renders;
  • invalid JSON recovers safely.

Commit:

git commit -am "Load saved books at startup"

The -a option stages modified tracked files, but not new untracked files. Use it only after confirming every modified tracked file belongs in the commit. Staging named files is safer for beginners.

Checkpoint 3: Save Add and Remove Actions

Update Add Book and Remove Book behavior.

Verify refresh persistence.

Commit:

git add app.js
git diff --staged
git commit -m "Persist book additions and removals"

Final Branch Review

Review all branch changes against main:

git diff main...HEAD

Run the full manual test checklist.

Only then merge the branch.

Checkpoints Make Debugging Faster

Suppose books begin disappearing after refresh.

Review history:

git log --oneline -8

You see:

a96c503 Persist book additions and removals
c714b20 Load saved books at startup
584bbd1 Add reading list storage helpers

This history gives you likely investigation points.

Use:

git show a96c503

to inspect how Add and Remove behavior changed.

Without focused commits, the same bug might be hidden inside one massive “complete app” change.

Checkpoints Make AI Prompts Better

Git history also gives the AI clearer context.

Instead of saying:

Something broke recently.

you can say:

The reading list worked at commit c714b20. The bug appeared after commit a96c503, which connected persistence to add and remove actions. Inspect the diff between those commits without editing files. Identify the most likely cause of removed books returning after refresh.

This prompt provides a narrow evidence boundary.

The AI can inspect the relevant change rather than guessing across the entire project.

Common Checkpoint Mistakes

Committing Untested AI Output

Generated code is not automatically a verified checkpoint.

Test it first.

Mixing Several Features

Filtering, storage, styling, and documentation should not be grouped merely because one AI session produced them.

Using Vague Commit Messages

Messages such as “update” make later recovery difficult.

Ignoring Untracked Files

A commit may look clean while logs, environment files, or generated output remain untracked.

Treating a Branch as a Backup

A branch without meaningful commits provides limited recovery value.

Creating Too Many Meaningless Commits

Do not commit every individual line.

Commit complete, reviewable units.

Keeping Broken Work in the Main Branch

Use a feature branch or temporary stash for uncertain experiments.

Rewriting Shared History Casually

Use revert commits when a published change needs to be reversed.

Forgetting to Test After a Merge or Revert

Repository operations can succeed while application behavior remains broken.

A Practical Checkpoint Decision Test

Before committing, ask:

  • Can I describe this change in one sentence?
  • Does the diff have one main purpose?
  • Did I review every changed file?
  • Did I test the intended behavior?
  • Did I test one related existing behavior?
  • Were unnecessary files and logs removed?
  • Were secrets excluded?
  • Does the commit message describe the result?
  • Would I trust this version as a recovery point?

When the answers are yes, the change is ready to become a checkpoint.

Recommended Git Rhythm for AI Coding

Use this rhythm during each focused feature:

1. Confirm the latest verified commit.
2. Confirm a clean or understood working tree.
3. Create a feature branch when the work is risky.
4. Give the AI one focused task.
5. Stop after the first coherent change.
6. Review Git status and diff.
7. Test the acceptance criteria.
8. Restore unrelated changes.
9. Stage specific files.
10. Review the staged diff.
11. Commit with a meaningful message.
12. Begin the next task from that checkpoint.

This rhythm reduces the chance that several uncertain AI changes become mixed together.

Practical Advice from Development Work

Git history is not only an archive.

It is part of the development process.

A clear commit before an AI experiment creates confidence because the experiment can be evaluated against a known state. A clear commit afterward records which version was reviewed and accepted.

In code review work, focused commits make intent easier to understand. They also make risky changes easier to isolate.

The same principle benefits beginners.

You do not need a complicated branching strategy. You need checkpoints that correspond to real, verified progress.

A Reusable Git Checkpoint Checklist

Before the AI Task

  • Run git status.
  • Review the latest commits.
  • Confirm the current branch.
  • Commit existing verified work.
  • Create a feature branch for uncertain work.
  • Define one task and acceptance criteria.

After the AI Change

  • Stop before starting another feature.
  • Run git status.
  • Inspect every changed file.
  • Run git diff.
  • Check new dependencies and untracked files.
  • Test the new feature.
  • Test related existing behavior.

Create the Checkpoint

  • Restore unrelated changes.
  • Stage named files.
  • Run git diff --staged.
  • Remove temporary logs.
  • Check for secrets.
  • Commit with a specific message.

After the Commit

  • Run git status.
  • Review the latest commit.
  • Push when appropriate.
  • Record unresolved work separately.
  • Begin the next feature from the verified state.

Conclusion

Git checkpoints give AI-assisted development a reliable structure.

A good checkpoint represents one focused change that has been reviewed, tested, and recorded with a meaningful commit message. Feature branches create space for uncertain experiments, while targeted restore and revert commands help recover when changes should not be kept.

The most useful workflow is:

Known state
→ Focused AI task
→ Review
→ Test
→ Commit

This approach does not slow vibe coding down. It prevents fast generation from turning into difficult recovery work.

The next article will focus on APIs and environment variables. We will examine how to connect the Personal Reading List Tracker to an external service without committing credentials, exposing private keys in browser code, or making the application depend completely on an unavailable API.

Frequently Asked Questions

Should I create a commit before every AI prompt?

Not every conversational question needs a commit.

Create a checkpoint before an AI task that may modify the project, especially when the current working state contains verified changes.

Should every feature use a separate branch?

No.

Small, low-risk changes can be completed directly on the main development branch when the working tree is clean and the project is personal. Use a branch for larger, uncertain, or multi-file experiments.

Is a Git stash the same as a checkpoint?

No.

A stash is temporary storage for unfinished work. A committed checkpoint is part of project history and should represent reviewed, meaningful progress.

Comments

Popular posts from this blog

Claude Code Multi-Agent Setup for Beginners: Models, Roles, and Your First Project

The Limits and Future of Vibe Coding

How to Test and Deploy Your First Vibe-Coded App