Apply the no-ai-slop standard (now binding in AGENTS.md): the em-dash character is banned outright (restructured, not blind-replaced), plus the banned word/phrase list (delve, leverage, robust, seamless, truly, unlock, etc.). 0 em-dashes remain in modules + capstone; the only "robust" left is the planted M10 ai-change.patch trap. Module H1 titles use a colon separator. All deliberate teaching devices preserved; labs compile/parse (py/sh/yaml/json); no junk. AGENTS.md updated with the hard no-slop rules. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfzV5QvtPDz8LJS3Pu5VLT
3.3 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.