title: "Practice Project: Agent-Assisted CLI Todo App" last_updated: 2026-03-21 status: proven difficulty: beginner prerequisites: [01-your-first-hour, 02-project-memory] estimated_time: "90 minutes"

Practice Project: Agent-Assisted CLI Todo App

Overview

You are going to build a command-line todo application from scratch, entirely through collaboration with an AI coding agent. The todo app itself is not the point. The point is practicing the agentic development skills you learned in Modules 00 through 02 — giving clear instructions, reviewing output critically, using project memory, and iterating effectively.

By the end of this project, you will have:

  • Scaffolded a project by giving an agent clear architectural direction
  • Built features using the plan-then-execute pattern
  • Created and tested a project memory file that measurably improves agent output
  • Used the test-first pattern to drive implementation through tests
  • Reflected on what the agent did well and where it needed correction

This project takes about 90 minutes. Each phase has a time estimate, but do not rush — the reflection at the end is where the learning compounds.

What You Will Build

A CLI todo app that supports adding tasks, listing them, marking them complete, and deleting them. The app stores todos in memory for now (persistence is a bonus challenge). It runs from the terminal and accepts commands as arguments.

What You Will Practice

SkillWhere Practiced
Clear architectural promptingPhase 1
Plan-then-execute patternPhase 2
Critical output reviewPhase 2
Project memory creation and testingPhase 3
Test-first agent patternPhase 4
Structured reflectionPhase 5

Prerequisites

Before starting, confirm all of the following:

  • Your agentic coding tool is installed and working (claude or codex)
  • Your API key is configured and you have verified it works by running a simple prompt
  • You have completed Module 01: Your First Hour and Module 02: Project Memory
  • You have a language runtime installed for your language of choice (Node.js, Python, Go, Rust — any works)
  • Git is installed and available on your system

Cost: This project will consume roughly $2-6 in API tokens depending on your language choice, how many iterations you need, and whether you attempt the bonus challenges.


Phase 1: Setup with the Agent (15 minutes)

Goal: Scaffold the project structure by giving the agent clear architectural instructions.

Step 1: Create the project directory

Create an empty directory for your todo app and initialize a git repository:

mkdir cli-todo-app
cd cli-todo-app
git init

Step 2: Start a session and give the agent your architecture

Start your agent and provide a prompt that covers four things: what to build, which language and tools to use, the basic structure, and any constraints. Here is a template:

I want to build a CLI todo app. Here are my requirements:

Language: [your choice — Python, Node.js, Go, etc.]
No external dependencies for core functionality.
The app should accept commands as CLI arguments, like:
  todo add "Buy groceries"
  todo list
  todo complete 1
  todo delete 1

Scaffold the project with:
- An entry point file
- A module for todo operations (add, list, complete, delete)
- A data structure to hold todos in memory
- A README with usage instructions

Do not implement the features yet — just set up the project structure
with placeholder functions.

Note: Adapt the language choice to your preference. The rest of this project uses Python in its examples, but every phase works with any language.

Step 3: Review the scaffold critically

Before accepting the agent's output, review it against these criteria:

  • Structure: Did it create the files you asked for? Are they organized sensibly?
  • Scope: Did it only scaffold, or did it start implementing features? If it implemented features you did not ask for, note that — scope creep from agents is common.
  • Conventions: Does the code follow standard conventions for your language?
  • Placeholders: Are the placeholder functions clear enough that you know what each one will do?

Run git diff (or git status for new files) to see exactly what the agent created. Commit the scaffold:

git add -A
git commit -m "Initial scaffold"

What to watch for

This phase is about architectural communication. Did the agent follow your structural instructions, or did it impose its own ideas? If it deviated, was its choice better than yours, or did it just ignore what you said? Both outcomes are instructive. If the agent made a better structural choice, you have learned something about the tool. If it ignored your instructions, you have learned something about how to be more specific.


Phase 2: Core Features (30 minutes)

Goal: Build the four core operations using the plan-then-execute pattern.

Step 1: Ask for a plan first

Do not ask the agent to implement all four features at once. Start with a plan:

Before writing any code, outline your plan for implementing these four
operations: add, list, complete, delete.

For each operation, describe:
- What data it needs
- What it does
- What output it produces
- What error cases it should handle

Review the plan. Does it match your expectations? Are the error cases reasonable? If something is off, correct it now — it is far cheaper to fix a plan than to fix an implementation.

Step 2: Implement one feature at a time

Work through the features in this order. For each one, give the agent a focused prompt, review the output, and commit before moving on.

Add:

Implement the "add" operation. It should accept a description string,
create a todo item with a unique ID, and store it in the in-memory list.
Print a confirmation message with the todo's ID.

Review the code. Run it. Does it work? Commit.

git add -A
git commit -m "Implement add operation"

List:

Implement the "list" operation. It should display all todos with their
ID, description, and status (pending or complete). If there are no todos,
print a helpful message instead of empty output.

Review, run, commit.

Complete:

Implement the "complete" operation. It takes a todo ID, marks that todo
as complete, and prints a confirmation. If the ID doesn't exist, print
an error message.

Review, run, commit.

Delete:

Implement the "delete" operation. It takes a todo ID, removes that todo
from the list, and prints a confirmation. If the ID doesn't exist, print
an error message.

Review, run, commit.

Step 3: Integration test by hand

Run through the full workflow manually:

# Adapt these commands to your language
python todo.py add "Buy groceries"
python todo.py add "Write report"
python todo.py list
python todo.py complete 1
python todo.py list
python todo.py delete 2
python todo.py list

If anything is broken, tell the agent what went wrong and let it fix it. Do not fix the code yourself — practice giving the agent clear feedback about the failure.

What to watch for

The plan-then-execute pattern is the key skill here. Notice how reviewing a plan before implementation lets you catch architectural issues early. Notice how working feature-by-feature with commits between each one gives you clean rollback points. Notice how focused prompts produce more reviewable output than a single "implement everything" prompt would.

Also pay attention to how the agent handles error cases. Did it handle edge cases you did not think of? Did it miss obvious ones? This tells you where the agent's judgment is reliable and where it needs your guidance.


Phase 3: Project Memory (15 minutes)

Goal: Create a CLAUDE.md (or AGENTS.md) for the todo app and measure its impact.

Step 1: Write the project memory file

Create a CLAUDE.md (for Claude Code) or AGENTS.md (for Codex CLI) in the project root. Write it yourself — do not ask the agent to write it. You know the project now. Keep it under 10 lines.

# CLAUDE.md

CLI todo app built with [your language]. No external dependencies.
Stores todos in memory (no persistence yet).

## Commands
- `[your run command] add "description"` — add a todo
- `[your run command] list` — show all todos
- `[your run command] complete <id>` — mark a todo done
- `[your run command] delete <id>` — remove a todo

## Conventions
- All user-facing output goes to stdout
- Errors go to stderr
- Exit code 0 on success, 1 on error
- [Add one convention specific to your language, e.g., "Use type hints on all functions"]

Commit it:

git add CLAUDE.md
git commit -m "Add project memory file"

Step 2: Test without project memory

Start a new session and ask the agent to add a feature without the project memory file available. Temporarily rename it:

mv CLAUDE.md CLAUDE.md.bak

Now start a fresh session and give this prompt:

Add an "edit" command that lets the user change the description of an
existing todo. Usage: todo edit <id> "new description"

Note the output. Pay attention to:

  • Did the agent understand the project structure?
  • Did it follow your existing conventions (output to stdout, errors to stderr, exit codes)?
  • Did it know how to run the app?
  • How many corrections did you need to make?

Do not commit this. Undo the changes:

git checkout .

Step 3: Test with project memory

Restore the project memory file and start a new session:

mv CLAUDE.md.bak CLAUDE.md

Give the exact same prompt:

Add an "edit" command that lets the user change the description of an
existing todo. Usage: todo edit <id> "new description"

Compare the output to the previous attempt:

  • Did the agent follow your conventions this time?
  • Did it structure the code consistently with the existing features?
  • How many corrections did you need?

If the project memory made a noticeable difference, commit this version:

git add -A
git commit -m "Add edit operation"

What to watch for

This is the experiment that makes project memory concrete. The side-by-side comparison shows you exactly what context the agent was missing and how a small configuration file fills the gap. Some differences will be dramatic (the agent now follows your error conventions). Others will be subtle (slightly more consistent code style). Both matter over the life of a project.


Phase 4: Testing (20 minutes)

Goal: Use the test-first pattern — ask the agent to write tests, then implement to make them pass.

Step 1: Ask the agent to write tests first

Write unit tests for the todo operations module. Cover these cases:

add:
- Adding a todo returns a todo with a unique ID
- Adding multiple todos assigns different IDs

list:
- Listing with no todos returns an empty list
- Listing returns all added todos with correct status

complete:
- Completing a valid ID changes status to complete
- Completing an invalid ID raises an error or returns an error indicator

delete:
- Deleting a valid ID removes the todo
- Deleting an invalid ID raises an error or returns an error indicator

Use [your language's standard test framework — pytest, jest, go test, etc.].
Do not modify the implementation — only write tests.

Step 2: Run the tests

# Adapt to your test runner
pytest tests/
# or: npm test
# or: go test ./...

Some tests may fail. That is expected — the test-first pattern intentionally reveals gaps between the test's expectations and the current implementation.

Step 3: Fix failures with the agent

For each failing test, tell the agent what failed and ask it to fix the implementation (not the test):

The test `test_complete_invalid_id` is failing because the complete
function doesn't raise a ValueError when given an ID that doesn't exist.
Fix the implementation to handle this case. Do not modify the test.

Run the tests again after each fix. Repeat until all tests pass.

Step 4: Commit

git add -A
git commit -m "Add unit tests and fix edge cases"

What to watch for

The test-first pattern flips the usual agent workflow. Instead of asking the agent to implement a feature and hoping it handles edge cases, you define the edge cases upfront as tests. The agent then has a concrete target: make the tests pass. This produces more reliable code because the agent is working toward an unambiguous success criterion instead of interpreting your intent.

Notice also how the agent handles the constraint "do not modify the test." Does it respect that boundary, or does it try to change the tests to match its preferred implementation? Agents sometimes resist constraints, and recognizing this tendency helps you enforce boundaries in larger projects.


Phase 5: Reflection (10 minutes)

Goal: Review what happened and capture lessons for future agent collaboration.

Step 1: Review the full project

Look at the complete codebase:

git log --oneline
git diff HEAD~5..HEAD --stat

Scan through the files. How much of this code did you write versus the agent? How much of the agent's code did you have to correct?

Step 2: Fill out the reflection template

Copy this template into a file or a scratch document. Answer each question honestly.

## Project Reflection

### What the agent did well
- [ ] Scaffolding and project structure
- [ ] Implementing straightforward CRUD operations
- [ ] Following conventions from CLAUDE.md
- [ ] Writing tests
- [ ] Other: ___

### What needed correction
- [ ] Scope creep (implemented more than asked)
- [ ] Missed error cases
- [ ] Inconsistent code style
- [ ] Ignored constraints
- [ ] Other: ___

### Key observations
1. The most effective prompt I wrote was: ___
2. The least effective prompt I wrote was: ___
3. The agent was fastest at: ___
4. The agent struggled most with: ___
5. Project memory made the biggest difference for: ___

### What I would do differently next time
1. ___
2. ___
3. ___

### Time spent
- Phase 1 (Setup): ___ minutes
- Phase 2 (Features): ___ minutes
- Phase 3 (Memory): ___ minutes
- Phase 4 (Testing): ___ minutes
- Phase 5 (Reflection): ___ minutes
- Total: ___ minutes

Step 3: Update your CLAUDE.md

Based on what you learned, add one or two lines to your project memory file. What did the agent get wrong that a configuration line could prevent next time?


Bonus Challenges

Each of these is a self-contained agent task. Use the skills you practiced above — plan first, implement incrementally, review critically, commit often.

Challenge 1: Add Persistence

Ask the agent to save todos to a JSON file so they survive between sessions. This tests whether the agent can modify an existing architecture (in-memory to file-based) without breaking the current interface.

Add file-based persistence to the todo app. Save todos to a todos.json
file in the current directory. Load from the file on startup, save after
every change. The CLI interface should not change — all existing commands
should work exactly as before.

Challenge 2: Add Priorities

Ask the agent to add priority levels (high, medium, low) to todos. This tests whether the agent can extend a data model and update all downstream code that touches it.

Add priority support. Each todo should have a priority: high, medium,
or low. Default to medium if not specified. Update the add command to
accept an optional --priority flag. Update the list command to show
priority and sort by priority (high first). Update the data model and
all relevant tests.

Challenge 3: Add Due Dates

Ask the agent to add due dates with overdue highlighting. This tests whether the agent handles dates correctly and integrates display logic.

Add due date support. The add command should accept an optional --due flag
with a date in YYYY-MM-DD format. The list command should show due dates
and highlight overdue items. Add a "todo overdue" command that lists only
items past their due date. Update tests to cover the new functionality.

What You Practiced

Use this checklist to map what you did back to the curriculum concepts.

ExerciseCurriculum ConceptModule
Giving the agent architectural instructionsClear prompting with intent and constraints03: Prompting
Reviewing scaffold output for scope creepCritical review of agent output01: Your First Hour
Plan-then-execute for featuresTask decomposition03: Prompting
Implementing one feature at a time with commitsSession architecture and checkpointing07: Session Architecture
Creating and testing CLAUDE.mdProject memory02: Project Memory
A/B testing with and without project memoryMeasuring project memory impact02: Project Memory
Test-first agent patternConstraining agent output with tests04: Hooks and Commands
Structured reflectionCalibrating trust and building intuition01: Your First Hour
Bonus challenges as self-directed agent tasksIndependent agentic developmentAll modules

If you completed all five phases and can check off at least six items in this table, you have a solid foundation. You are ready for the intermediate modules.