todoist-cli
AGENTS.md331 starsChanged 7 days agoMITView on GitHub
For repo structure, where things live, and shared utilities, read CODEBASE.md first. This file covers the rules; CODEBASE.md is the map. TypeScript CLI for Todoist. Binary name: td. Use the matching skill without being asked. They live in .agents/skills/ (Claude Code reads them through .claude/skills/). Reviewers, Doistbot included, apply these to every change: Two-tsconfig setup: tsconfig.json includes both source and test files — used by type-check and IDEs. tsconfig.build.json extends it but excludes colocated *.test.ts files plus src/test-support/ — used…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository11 other files it gives its agents.
- docs/agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-commandSkill
- build-featureSkill
- fix-bugSkill
- learnSkill
- refactorSkill
- review-changesSkill
- verifySkill
- write-testsSkill
- todoist-cliSkill
The file
We split this AGENTS.md into the rules it gives an agent
9 rules. About 0 are common, 1 is distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 13
Never weaken a check to pass it: Don't skip, delete or loosen tests, edit lint, type or test config to get green, or use --no-verify.
- Very specific: line 18
Use the matching skill without being asked.
- Very specific: line 62
Use this to see a change working, on top of npm run verify.
- Distinctive: line 77
When adding features, add corresponding tests.
- Very specific: line 83
When a turn changes code that npm run verify has not passed, the end-of-turn hook (Claude Code, Codex, Cursor) sends you back once.
- Very specific: line 100
Run npm run sync:skill to regenerate skills/todoist-cli/SKILL.md (builds automatically)
- Very specific: line 101
Run td skill update claude-code (and any other installed agents) to propagate changes to installed skill files
- Very specific: line 128
Delete, complete, uncomplete, archive, and unarchive commands support --json through src/lib/mutation-json.ts.
- Very specific: line 146
Follow docs/icon.md. The consent-screen icon is stored on the Todoist CLI app, not read from icons/, so replacing the repo file alone does …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Todoist CLI
For repo structure, where things live, and shared utilities, read CODEBASE.md first. This file covers the rules; CODEBASE.md is the map.
TypeScript CLI for Todoist. Binary name: td.
Definition of done
- Done means proven: a test that failed before the change and passes after, or the command's real output (
node dist/index.js <command>, on a test account). For a refactor: tests that pin the behaviour, passing before and after. Reading code or a passing compile is not proof. - Run
npm run verifybefore calling a change done. It runs every check CI runs, in about fifteen seconds, and records the pass. It prints what it cannot see, and says when only docs changed and there is nothing to check. - Never weaken a check to pass it. Don't skip, delete or loosen tests, edit lint, type or test config to get green, or use
--no-verify. If a check looks wrong, say so and stop. - Report honestly: what ran, what it showed, and what you did not verify.
Skills
Use the matching skill without being asked. They live in .agents/skills/ (Claude Code reads them through .claude/skills/).
verify: before saying a change is done, fixed or ready.fix-bug: something is broken or wrong.build-feature: a new command, flag or behaviour.add-command: the checklist of files to touch for a new command or subcommand.refactor: changing structure without changing behaviour. Other tasks send restructuring here, as a separate change.write-tests: writing or changing tests;.agents/skills/write-tests/references/test-rules.mdis the quality bar.learn: after a correction, to turn it into a check.review-changes: when the owner says a change is ready for a PR, or asks for a review.
Review checks
Reviewers, Doistbot included, apply these to every change:
- Tests: not weakened, new behaviour tested.
- Architecture: rules lint can't express.
- Security: the token, read-only mode, extensions, shelling out.
- Privacy and secrets: this repository is public.
- Command surface: what people, scripts and agents see.
- Evidence: claims backed by what ran.
Build & Run
npm run build # compile TypeScript (uses tsconfig.build.json, excludes tests)
npm run dev # watch mode (uses tsconfig.build.json)
npm run type-check # type check source + tests (tsconfig.json) and the agent tooling (.agents/scripts)
npm run check # lint + format check
npm run fix # auto-fix lint + format
npm test # run tests
npm run verify # every check CI runs (lint, format, types, tests, build, skill sync)Two-tsconfig setup: tsconfig.json includes both source and test files — used by type-check and IDEs. tsconfig.build.json extends it but excludes colocated *.test.ts files plus src/test-support/ — used by build and dev to keep test-only code out of dist/.
Run the CLI directly (no linking needed):
node dist/index.js --help # show commands
node dist/index.js today # run 'today' command
node dist/index.js <command> ... # run any commandUse this to see a change working, on top of npm run verify.
Rules when changing code
- Named flag aliases: where commands accept positional args for context (project, task, workspace), named flags (
--project,--task,--workspace) are also accepted. Error if both positional and flag are provided. - Implicit
viewsubcommand edge case:td project <ref>defaults totd project view <ref>. If a project/task name matches a subcommand name (e.g.,"list"), the subcommand wins — users must usetd project view list. - API response shape: client returns
{ results: T[], nextCursor? }— always destructure. - Priority mapping: CLI uses
"p1"–"p4"strings; API uses 4=p1 (highest), 1=p4 (lowest). UseparsePriorityfromsrc/lib/task-list.ts, never hand-roll. - Errors: throw
CliError(code, message, hints?)fromsrc/lib/errors.tsfor anything user-facing. The globalparseAsync().catchinsrc/index.tsrenders it correctly in JSON and pretty modes. The same handler also matchesBaseCliError(re-exported fromsrc/lib/errors.ts) so errors thrown by@doist/cli-corehelpers route through the same formatter.
Testing
Tests use vitest with mocked API. npm run verify runs them with every other CI check.
- Co-locate tests next to the command or lib module they cover.
- When adding features, add corresponding tests.
- See CODEBASE.md for the mock-api + fixtures setup.
Git hooks and agent tooling
- Commits and pushes to
mainare refused by the git hooks. Work on a branch. - When a turn changes code that
npm run verifyhas not passed, the end-of-turn hook (Claude Code, Codex, Cursor) sends you back once. Run verify, or stop on purpose and say what is unverified. - Agent tooling lives in
.agents/scripts/, never inscripts/(which ships in the npm package). - How it all fits together:
docs/agents.md.
Skill Content (Agent Command Reference)
The file src/lib/skills/content.ts exports SKILL_CONTENT — a comprehensive command reference that gets installed into AI agent skill directories via td skill install. This is the source of truth that agents use to understand available CLI commands.
Whenever commands, subcommands, flags, or options are added, updated, or removed in src/commands/, the SKILL_CONTENT in src/lib/skills/content.ts must be updated to match. This includes:
- Adding new commands or subcommands with usage examples
- Adding, removing, or renaming flags and options
- Updating the Quick Reference section when new top-level commands are introduced
- Keeping examples accurate and consistent with actual CLI behavior
After updating SKILL_CONTENT:
- Run
npm run sync:skillto regenerateskills/todoist-cli/SKILL.md(builds automatically) - Run
td skill update claude-code(and any other installed agents) to propagate changes to installed skill files
A CI check (npm run check:skill-sync) runs on pull requests and will fail if skills/todoist-cli/SKILL.md is out of sync with content.ts.
JSON Output for Mutating Commands
Entity add/create/update commands support --json to output the created or updated entity as machine-readable JSON instead of the default human-readable confirmation message. This applies to:
task add,task updateproject create,project updatecomment add,comment updatelabel create,label updatefilter createsection create,section updatereminder add
When adding new add/create/update commands, always include a --json flag that outputs the resulting entity using formatJson(result, entityType) from src/lib/output.ts. The pattern is:
const result = await api.addXxx(args)
if (options.json) {
console.log(formatJson(result, 'entityType'))
return
}
// normal human-readable outputDelete, complete, uncomplete, archive, and unarchive commands support --json through
src/lib/mutation-json.ts. Since they return no entity, successful writes emit
ok, command, and messages. Dry runs emit status: "preview", command, and
messages, without claiming success. Add new no-entity mutations to that registry.
Errors are rendered by the global JSON error handler.
Keeping CODEBASE.md accurate
CODEBASE.md is a structural map, not a file index. Update it when structure changes — not on every new file. Triggers:
- new top-level dir under
src/, or a new command-group folder - a new broadly-reusable helper in
src/lib/(the "don't reimplement" catalog) - changes to command registration, auth/token storage, or build/test/release tooling
Adding a single subcommand to an existing group, or a narrowly-scoped helper used by one caller, does not require an update.
Changing the CLI icon
Follow docs/icon.md. The consent-screen icon is stored on the Todoist CLI app, not read from icons/, so replacing the repo file alone does not change it. Never rename or delete files in icons/.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

