Scaffold the course repo and author the full curriculum in dependency-chain order, following the settled build decisions in handoff.md. - Scaffold: course README, vendor-neutral AGENTS.md (dogfoods Module 5), _TEMPLATE.md (the fixed 9-section module shape), root .gitignore, ship config. - Modules 1-2: reference exemplars (locked for tone/depth/lab style). - Modules 3-27: full lessons + runnable labs, each following the template, respecting the chain, vendor/model-agnostic, with "feel the pain" labs. - Module 8 hosting comparison web-researched and date-stamped (as of 2026-06-22), not written from memory; expansion-zone modules carry Verify-before-publish. - Capstone: the full loop end to end on the running tasks-app example. Lab code syntax-checked (Python/shell/YAML); every module has the 7 core template sections. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfzV5QvtPDz8LJS3Pu5VLT
3.4 KiB
Skill: Add a new tasks-app command, end to end
A reusable playbook. Don't paste this whole file into a chat and hope. Point your agentic tool at it by name — "follow
add-command.mdto add aclearcommand" — or drop it wherever your tool auto-discovers procedures (a skills/commands folder). The steps are the same either way.
When to use this
Invoke this whenever the task is "add a new subcommand to the tasks-app CLI." It exists so a
new command lands the same way every time: real code, a real test, a changelog line, and a clean
commit — never just the code with the rest forgotten.
If the task is not "add a CLI command" (a bug fix, a refactor, a docs change), this skill does not apply. Don't force it.
Inputs you need before starting
Ask for these if they weren't given:
COMMAND_NAME— the subcommand word, e.g.clear.WHAT_IT_DOES— one sentence of intended behavior, e.g. "remove all tasks."
Project facts (so you don't have to rediscover them)
- Core logic lives in
tasks.py(theTaskListclass). The CLI front end iscli.py. State persists totasks.json— never edittasks.jsonby hand; it's generated. - Tests live in
test_tasks.pyand run withpython -m unittest. Standard library only — no third-party packages, no new dependencies. - The human-facing change log is
CHANGELOG.md, newest entry on top.
Procedure — do these in order, do not skip
-
Core logic in
tasks.py. If the command needs new behavior on the task list, add a small method toTaskList(e.g.clear()). Keep it minimal; match the existing style. If the command only reads existing state, skip to step 2. -
Wire the CLI in
cli.py. Add a branch tomain()forCOMMAND_NAME, call intotasks.py,save()if it mutated state, and print a short confirmation. Add the command to theusage:string so it's discoverable. -
Add a real test in
test_tasks.py. Test the behavior you intended, not just "it doesn't crash." Assert the end state (e.g. afterclear(),len(tasks) == 0andpending()is empty). A test that passes against a broken implementation is worse than no test. -
Run the tests.
python -m unittestfrom the project root. Do not claim success until it's green. If it fails, fix the code — not the test — and run again. -
Smoke-test the CLI. Actually run it:
python cli.py COMMAND_NAME, thenpython cli.py listto confirm the visible result. Paste what you ran and what it printed. -
Add a
CHANGELOG.mdentry. One line under the top heading, present tense:- Add \COMMAND_NAME` command: WHAT_IT_DOES.` Newest on top. -
Commit as one logical change. Stage code + test + changelog together and commit with a message that names the command:
git add tasks.py cli.py test_tasks.py CHANGELOG.md && git commit -m "Add COMMAND_NAME command". Do not stagetasks.json.
Done when
python -m unittestis green and includes a new test that actually exercisesCOMMAND_NAME.python cli.py COMMAND_NAMEdoesWHAT_IT_DOESand you've shown the output.CHANGELOG.mdhas a new top line for the command.- One commit contains the code, the test, and the changelog line — and nothing else (no
tasks.json, no unrelated reformatting).
If any of those is missing, the skill isn't finished. Report which step failed and stop — don't paper over it.