Turing Guild Labs

Back to course

Lab

Lab: Build Your First Habitat CLI with Codex

Submit this lab

Lab: Build Your First Habitat CLI with Codex

In the previous class exercise, you helped design basic objects for an exoplanet habitat CLI.

In this lab, you will start building the first working version of that CLI with Codex.

The goal is not to create the entire final project in one giant prompt. The goal is to work in small steps:

  1. ask Codex for one small feature
  2. run and test it
  3. explain what worked or did not work
  4. ask Codex for the next small improvement

This is how real software gets built: one working slice at a time.

What You Are Building

You are building a command-line app called something like habitat.

Your CLI should eventually help a user manage objects from the shared class exercise notes, such as zones, airlocks, sensors, rovers, greenhouses, or other habitat objects.

Start simple. A tiny CLI that actually runs is better than a huge plan that does not work.

Before You Start

You should have the shared object-card notes from the class exercise. Use the notes area in the LMS as your reference while you work.

Those notes should include:

  • 5-7 habitat objects
  • basic properties for each object
  • basic actions for each object
  • CRUD-style commands you might want your CLI to support

CRUD means:

Create: add a new thing
Read: list things or show details for one thing
Update: change a thing
Delete: remove a thing

Important Rule: Do Not One-Shot This

Do not give Codex one huge prompt asking it to build the entire CLI at once.

Instead, work in small checkpoints. Each checkpoint should leave you with something you can run and test.

The prompt examples below are written as multi-line code blocks. Copy the whole block when you want to use one.

Before asking Codex to build or change the CLI, use the Shift+Tab shortcut to switch Codex into plan mode. Let Codex ask clarifying questions if it needs more information. Then read the plan before you accept it so you understand what Codex is about to do.

A good first Codex prompt might look like this:

Create the smallest Bun and TypeScript command-line app named habitat.

Use established libraries instead of manually implementing behavior when a library already provides it.

For command-line parsing, options, help text, version output, and unknown-command handling, use Commander.js.
Do not write your own argument parser.

For this first version, only implement:
- habitat --help
- habitat --version
- a friendly message when an unknown command is used

Use a simple project structure.
Configure the project so I can run `bun install`, then `bun link`, and then use the `habitat` command directly.
Do not add habitat objects yet.
After creating it, tell me exactly what commands to run to install, link, and test it.

Then after you test it, your next Codex prompt might be:

Now add commands for one object: zone.

A zone should have these properties:
- name
- purpose
- status

For now, store zones in a simple local JSON file so data survives between command runs. Do not use a database yet.
Add commands for:
- create a zone
- list zones
- show one zone
- update a zone
- delete a zone

Keep the implementation simple.
After the change, tell me the exact commands I should run to test each command.

Then after you test that, you might ask for another object:

Now add the same CRUD pattern for airlocks.

An airlock should have these properties:
- name
- pressureLevel
- locked

Follow the same command style as the zone commands.
Update the help text so the new airlock commands are discoverable.
Tell me exactly what commands to run to test the new behavior.

Small steps are the point.

Step 1: Create a Project Folder

Create a new folder for your lab work.

Example:

cd ~/labs
mkdir habitat-cli
cd habitat-cli

If your class uses a different labs folder, use that location instead.

Step 2: Ask Codex for the Smallest Possible CLI

Open Codex in your project folder.

Use Shift+Tab to put Codex into plan mode before you send your build prompt. If Codex asks clarifying questions, answer them. Read the plan before you approve the work.

Your first goal is only to get a CLI that runs.

In your first prompt, tell Codex to use established libraries instead of manually implementing behavior when a library already provides it. For this CLI, tell Codex to use Commander.js for arguments, options, help text, version output, and unknown commands.

Use a prompt like this:

Create the smallest Bun and TypeScript command-line app named habitat.

Use established libraries instead of manually implementing behavior when a library already provides it.

For command-line parsing, options, help text, version output, and unknown-command handling, use Commander.js.
Do not write your own argument parser.

For this first version, only implement:
- habitat --help
- habitat --version
- a friendly message when an unknown command is used

Use a simple project structure.
Configure the project so I can run `bun install`, then `bun link`, and then use the `habitat` command directly.
Do not add habitat objects yet.
After creating it, tell me exactly what commands to run to install, link, and test it.

After Codex builds it, install and link it once.

Try commands like:

bun install
bun link
habitat --help
habitat --version
habitat nonsense

You may see Codex suggest both bun link and bun link habitat. For this lab, start with just bun link from inside your habitat-cli project folder. That should make the habitat command available. bun link habitat is usually for linking the package into a different project, so you normally do not need it here.

Your first checkpoint is complete when:

  • bun install completes
  • bun link makes the habitat command available
  • you understand that bun link habitat is usually not needed inside this same project
  • the CLI starts without crashing
  • help text appears
  • the version appears
  • unknown commands are handled clearly

Step 3: Add One Object First

Pick one object from the shared object-card notes.

Choose the simplest one first. Good first choices might be:

  • zone
  • sensor
  • rover
  • airlock
  • greenhouse

Ask Codex to add only that object.

Example:

Now add one object to the CLI: zone.

A zone should have these properties:
- name
- purpose
- status

For now, store zones in a simple local JSON file so data survives between command runs. Do not use a database yet.
Add commands for:
- create a zone
- list zones
- show one zone
- update a zone
- delete a zone

Keep the implementation simple.
After the change, tell me the exact commands I should run to test each command.

Test the commands Codex gives you.

You might end up with commands like:

habitat zone create greenhouse --purpose "grow food"
habitat zone list
habitat zone show greenhouse
habitat zone update greenhouse --status active
habitat zone delete greenhouse

Your command names may be different. That is fine. What matters is that they are clear and testable.

Step 4: Tell Codex What Happened

After you test, report the results back to Codex.

Be specific. Include the command you ran and what happened.

Useful follow-up prompts look like this:

I tested the zone commands.

This command worked:
habitat zone create greenhouse --purpose "grow food"

This command did not work:
habitat zone show greenhouse

The output said the zone could not be found.
Please inspect the code, explain why this is happening, and fix the bug.
After the fix, tell me which commands to rerun.

Or, if the feature works but needs polish:

The zone commands work now.

Please improve the help text so the zone commands are easy to discover.
I want habitat --help to show the main command groups.
I want habitat zone --help to show examples for create, list, show, update, and delete.

Or, if you want to rename a command:

The command works, but I do not like the command name.

Please rename zone show to zone status.
Update the help text and examples everywhere.
Tell me exactly what commands to run to verify the rename.

Do not just say "it does not work." Tell Codex what command you ran and what happened.

Step 5: Add Connected Objects

After one object works, add two objects that can be connected to each other.

This is where your CLI starts to show object relationships. For example, a habitat might have doors, and an airlock might use two of those doors.

Use the same small-step pattern:

  1. describe the first object
  2. describe the second object
  3. ask for CRUD commands for each object
  4. ask for one command that connects them
  5. test the commands
  6. inspect the JSON file to see how the relationship was saved
  7. ask Codex to fix or refine anything confusing

Example:

Now add two connected objects: doors and airlocks.

A door should have these properties:
- name
- status
- locked

An airlock should have these properties:
- name
- pressureLevel
- locked

Add CRUD commands for doors.
Add CRUD commands for airlocks.
Add a command that attaches a door to an airlock, such as:
- habitat airlock add-door <airlockName> <doorName>

Store everything in the same simple local JSON file.
When a door is attached to an airlock, choose a simple way to save that relationship.

After the change, tell me exactly what commands I should run to test:
- creating two doors
- creating one airlock
- attaching both doors to the airlock
- showing the airlock with its doors
- inspecting the JSON file

You might end up with commands like:

habitat door create inner-door --status closed --locked true
habitat door create outer-door --status closed --locked true
habitat airlock create main-airlock --pressure-level 101 --locked true
habitat airlock add-door main-airlock inner-door
habitat airlock add-door main-airlock outer-door
habitat airlock show main-airlock

After those commands work, open the JSON file and look at how Codex saved the relationship. Did it put the full door objects inside the airlock? Did it store door names or IDs? Did it use another structure?

Step 6: Keep Building Object by Object

Continue adding objects from the shared object-card notes.

Do not add everything at once. Add one object or one relationship, test it, then move on.

A good order might be:

  1. zones
  2. sensors
  3. airlocks
  4. rovers
  5. greenhouses

You can choose a different order based on the object cards.

Step 7: Improve Help and Discoverability

A good CLI should teach both people and AI agents how to use it.

Ask Codex to improve the help text so another AI agent could inspect the help output and then use the CLI correctly. The help should make the command groups, arguments, options, examples, and expected outputs clear.

Example:

Improve the CLI help text so that the CLI is very discoverable by a coding agent that wants to use it.

After updating the help text, tell me the commands I should run to inspect it.

Then test:

habitat --help
habitat zone --help
habitat airlock --help

Step 8: Check That Your CLI Remembers Data

A CLI command starts fresh each time you run it. If your objects only live in memory, the CLI will forget them on the next command.

That is why this lab asks you to use a simple local JSON file. After your first object works, test that the data survives across separate command runs.

Example test:

habitat zone create greenhouse --purpose "grow food"
habitat zone list

If the second command does not show the zone you created, tell Codex exactly what happened.

Example follow-up prompt:

I created a zone and then ran zone list as a separate command.

The zone did not appear in the list.
Please inspect the persistence code and make sure zones are saved to and loaded from a simple local JSON file.
Do not use a database.
After the fix, tell me which commands to rerun.

Keep persistence simple. The goal is just to make your CLI remember data between command runs.

What To Submit

Submit a short screen recording or written summary that shows:

  • your CLI running --help and --version
  • CRUD commands working for at least one habitat object
  • doors and airlocks connected through a command such as habitat airlock add-door
  • the JSON file showing how that relationship is stored
  • at least one moment where you tested something and asked Codex to refine or fix it
  • the current list of objects your CLI supports

You do not need a perfect final CLI. You need to show that you can build, test, and improve it in small steps with Codex.

Success Checklist

Before you finish, make sure you can answer yes to these:

  • Did we start with a tiny CLI that runs?
  • Did we avoid one giant prompt?
  • Did we add one object first?
  • Did we test create, list/show, update, and delete commands?
  • Did we connect two objects, such as doors and an airlock?
  • Did we inspect the JSON file to see how the relationship was stored?
  • Did we use Codex to refine the CLI after testing?
  • Does the help text make the CLI easier to discover?

Submit Your Lab With GitHub

Before you start any stretch work, save your core lab work in GitHub.

Make sure you are inside your lab directory. The path should end with:

labs/habitat-cli

Initialize Git, commit your work, create a public GitHub repository, and push it:

git init
git add .
git commit -m "Complete Habitat CLI lab"
gh repo create habitat-cli --public --source=. --remote=origin --push

Get the URL for your GitHub repository:

gh repo view --web

Copy the GitHub repository URL from your browser and submit that URL with your lab submission.

Stretch Lab Options

After your core CLI works, choose one optional stretch direction to extend it.

Do not start stretch work until your CLI can run --help and --version, and at least one habitat object supports create, list or show, update, and delete.

Choose one:

  • add JSON output for one or more commands
  • add stronger help examples for each object command
  • add import or export commands for your JSON data file
  • add validation for required fields and clear error messages
  • add a habitat status command that summarizes the current habitat
  • add another relationship between two objects, such as assigning a sensor to a zone or a rover to a garage
  • improve how airlocks show their attached doors, especially if the JSON file stores only door names or IDs

When you ask Codex for stretch work, keep using small prompts. Use plan mode, read the plan, describe the one improvement you want, test it, and then decide whether to refine it.

For relationship-focused stretch work, make sure you actually look at the JSON file. Notice whether Codex saved relationships as nested arrays, nested objects, IDs, names, or some other structure. Be ready to explain what you found in plain language.