Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions skills/todoist-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ Choosing between `task add` and `task quickadd`:
- Use `td task add` when you need flags that Quick Add syntax can't express (`--deadline`, `--description`, `--parent`, `--duration`, `--uncompletable`, `--order`), when the text is being composed programmatically, or when you need explicit `id:` / URL references for project/section/parent.
- `td task quickadd` supports `--stdin`, `--json`, and `--dry-run` only; everything else is embedded in the text.
- The top-level `td add <text>` is a human shorthand for `td task quickadd` — same parser, same flag surface (`--stdin`, `--json`, `--dry-run`). Agents should prefer `td task quickadd` / `qa` for discoverability alongside the other task subcommands.
- `--due` on `task add` / `task update` is **sent verbatim** to the API as `due_string` — the CLI does not parse or rewrite it. The server's `due_string` parser handles simple inputs ("2026-06-01", "tomorrow", "every Monday") but does **not** unpack some more complex clauses (i.e. `starting <date>`). For complex natural-language input on new tasks, prefer `td task quickadd`, which routes through Todoist's quick-add parser.

Useful task flags:
- `--stdin` on `task add` reads the task description from stdin; on `task quickadd` (and the top-level `td add`) it reads the full natural-language text from stdin.
Expand Down
25 changes: 23 additions & 2 deletions src/commands/task/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Examples:
.command('add [content]')
.description('Add a task')
.option('--content <text>', 'Task content (legacy, prefer positional argument)')
.option('--due <date>', 'Due date (natural language or YYYY-MM-DD)')
.option('--due <date>', 'Due date (YYYY-MM-DD or simple natural language; see Notes below)')
.option('--deadline <date>', 'Deadline date (YYYY-MM-DD)')
.addOption(
withCaseInsensitiveChoices(
Expand Down Expand Up @@ -157,6 +157,16 @@ Examples:
}
return addTask({ ...options, content })
})
.addHelpText(
Comment thread
engfragui marked this conversation as resolved.
'after',
`
Notes:
--due is sent verbatim as the task's due_string. The server's due_string
parser handles simple inputs ("2026-06-01", "tomorrow", "every Monday") but
does not unpack some more complex clauses (i.e. "starting <date>"). For complex
natural-language input, prefer using quickadd, which routes through Todoist's
quick-add parser.`,
)

const quickaddCmd = task
.command('quickadd [text]')
Expand All @@ -179,7 +189,10 @@ Examples:
.command('update [ref]')
.description('Update a task')
.option('--content <text>', 'New content')
.option('--due <date>', 'New due date')
.option(
'--due <date>',
'New due date (YYYY-MM-DD or simple natural language; see Notes below)',
)
.option('--no-due', 'Remove due date')
.option('--deadline <date>', 'Deadline date (YYYY-MM-DD)')
.option('--no-deadline', 'Remove deadline')
Expand Down Expand Up @@ -216,6 +229,14 @@ Examples:
}
return updateTask(ref, options)
})
.addHelpText(
'after',
`
Notes:
--due is sent verbatim as the task's due_string, with the same caveats as
"task add --due": the server's due_string parser does not unpack some more
complex clauses (i.e. "starting <date>").`,
)

const moveCmd = task
.command('move [ref]')
Expand Down
34 changes: 34 additions & 0 deletions src/commands/task/task.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2768,3 +2768,37 @@ describe('task (no args)', () => {
stdoutSpy.mockRestore()
})
})

describe('task add/update --due help text', () => {
async function captureHelp(args: string[]): Promise<string> {
const program = createProgram()
const stdoutSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true)

await expect(program.parseAsync(['node', 'td', ...args])).rejects.toThrow()

const output = stdoutSpy.mock.calls.map((c) => String(c[0])).join('')
stdoutSpy.mockRestore()
return output
}

it('task add --help documents the verbatim caveat and points to quickadd', async () => {
const output = await captureHelp(['task', 'add', '--help'])

expect(output).toContain('--due')
expect(output).toContain('Notes:')
expect(output).toContain('sent verbatim')
expect(output).toContain('"starting <date>"')
expect(output).toContain('quick-add parser')
})

it('task update --help documents the verbatim caveat and refers back to task add --due', async () => {
const output = await captureHelp(['task', 'update', '--help'])

expect(output).toContain('--due')
expect(output).toContain('Notes:')
expect(output).toContain('sent verbatim')
expect(output).toContain('"starting <date>"')
expect(output).toContain('same caveats as')
expect(output).toContain('"task add --due"')
})
})
1 change: 1 addition & 0 deletions src/lib/skills/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ Choosing between \`task add\` and \`task quickadd\`:
- Use \`td task add\` when you need flags that Quick Add syntax can't express (\`--deadline\`, \`--description\`, \`--parent\`, \`--duration\`, \`--uncompletable\`, \`--order\`), when the text is being composed programmatically, or when you need explicit \`id:\` / URL references for project/section/parent.
- \`td task quickadd\` supports \`--stdin\`, \`--json\`, and \`--dry-run\` only; everything else is embedded in the text.
- The top-level \`td add <text>\` is a human shorthand for \`td task quickadd\` — same parser, same flag surface (\`--stdin\`, \`--json\`, \`--dry-run\`). Agents should prefer \`td task quickadd\` / \`qa\` for discoverability alongside the other task subcommands.
- \`--due\` on \`task add\` / \`task update\` is **sent verbatim** to the API as \`due_string\` — the CLI does not parse or rewrite it. The server's \`due_string\` parser handles simple inputs ("2026-06-01", "tomorrow", "every Monday") but does **not** unpack some more complex clauses (i.e. \`starting <date>\`). For complex natural-language input on new tasks, prefer \`td task quickadd\`, which routes through Todoist's quick-add parser.

Useful task flags:
- \`--stdin\` on \`task add\` reads the task description from stdin; on \`task quickadd\` (and the top-level \`td add\`) it reads the full natural-language text from stdin.
Expand Down
Loading