Skip to content

feat(filter): sort tasks the way the Todoist apps do - #478

Closed
craigcarlyle wants to merge 138 commits into
nextfrom
craigcarlyle/fix-issue-473
Closed

feat(filter): sort tasks the way the Todoist apps do#478
craigcarlyle wants to merge 138 commits into
nextfrom
craigcarlyle/fix-issue-473

Conversation

@craigcarlyle

Copy link
Copy Markdown

td filter view now orders tasks the way the Todoist apps order them, instead of printing whatever order the API returned.

The cause. Todoist doesn't sort server-side. GET /tasks/filter returns storage order, roughly date added ascending, which is why the reporter found that setting their filter to "date added asc" made the app match the CLI. Clients sort locally: by the sorting saved on the view (sorted_by on the view_options Sync resource), and when the view has none, by a documented default. For filters without date queries that default is priority, then date and time, then deadline, then project order, then task order. Filters that query dates lead with date. The CLI read neither piece.

Two new modules. src/lib/task-sort.ts holds the ordering, kept out of the filter command so today, upcoming and label view can pick it up later. src/lib/api/view-options.ts reads the saved options with a direct POST to /sync rather than api.sync(): the SDK schema types object_id as a required string, but the API returns null for the Today and Upcoming rows, so a typed sync throws for anyone who has customised either view. Confirmed against a live account, and worth its own SDK issue.

New flags: --sort <field> and --sort-order asc|desc, with precedence running flag, saved view, Todoist default. --sort none gives back the raw API order.

Not addressed: grouping. grouped_by is still ignored, so a filter grouped by date or label renders flat. That overlaps with #462.

Verification. 1838 tests pass, 43 of them new. Live check on a default-sorted filter with date queries, where date leads and priority breaks the tie:

$ td filter show <filter-id> --all --json | jq -r '.sections[0].results[] | "p\(5 - .priority)  \(.due.date)"'
p4  2026-08-15
p4  2026-08-15
p3  2026-08-17
p3  2026-08-17
p4  2026-08-17

Closes #473

scottlovegrove and others added 30 commits May 24, 2026 09:05
…tachers (#360)

## Summary
- Rename the top-level `td user` command group to `td accounts`, keeping
`user` and `users` as non-breaking aliases (wired through the lazy
command dispatcher; tab-completion suggests all three).
- Move **all four** account subcommands onto cli-core's generic
attachers, so they run on the `TokenStore` contract instead of
hand-rolled logic:
  - `accounts list` → `attachAccountListCommand`
  - `accounts use` / `default` → `attachAccountUseCommand`
  - `accounts current` → `attachAccountCurrentCommand`
  - `accounts remove` → `attachAccountRemoveCommand`
- Unify the "default account" rule (`getEffectiveDefaultUserId`) across
`auth status` and `config view` (the `list`/`current` markers come from
the store directly).
- Update user-facing hints across the CLI to point at `td accounts …`.

## cli-core dependency
Requires **@doist/cli-core 0.23.0** (now pinned) — the release
containing all four account attachers plus the `TokenStore` contract
changes (`clear()` returns `ClearedAccount`, new optional
`activeAccount()`).

## Behavior changes
- **`accounts list --json`/`--ndjson`**: cli-core's `{ accounts, default
}` envelope (per-account entries keep the existing camelCase fields).
The `storage` field is dropped (`store.list()` has no token-source
info); empty `--json` is `{"accounts":[],"default":null}`.
- **`accounts current`**: output preserved (stored account renders with
accurate `source`; env/legacy via `onNotAuthenticated`). Gains
`--ndjson`. An `activeAccount` env-override is added to the store
adapter so `TODOIST_API_TOKEN` still wins over a stored default.
- **`accounts remove`**: `store.clear(ref)` resolves + deletes by
canonical id and reports `wasDefault` (token-free, so a broken keyring
entry stays removable). Gains `--json` (`{ ok, removed }`) / silent
`--ndjson`; human output and the keyring-fallback warning preserved.
- **`accounts use` / `remove`**: don't honor `--quiet` and use
Commander's required-arg error for a missing `<ref>` — both are
cli-core-wide attacher behaviors (also true of `auth
login`/`logout`/`status`); proper fixes belong in cli-core's `emitView`.
- **Aliases**: `td user …` and `td users …` continue to work unchanged.

## Versioning
The `accounts list --json` reshape is an intentional, low-impact change
to a niche list-users machine surface; shipping as a minor `feat` (not
`BREAKING CHANGE`).

## Test plan
- [x] `npm run type-check`
- [x] `npm test` (1654 pass)
- [x] `npm run check` (oxlint + oxfmt)
- [x] `check:skill-sync`
- [x] Smoke-tested `accounts list/current/remove` (+
`--json`/`--ndjson`, env-token path) and the `user`/`users` aliases
against the linked cli-core build
## [1.69.0](v1.68.0...v1.69.0) (2026-05-24)

### Features

* rename `td user` to `td accounts` and adopt cli-core account attachers ([#360](#360)) ([73a0b77](73a0b77))
## Summary
- Replace local `src/test-support/program.ts` + `console-spy.ts` with
the published `@doist/cli-core/testing` helpers — stop reinventing
scaffolding the CLIs share (per cli-core#49).
- `createTestProgram` is byte-identical to cli-core's; console/stream
spies map 1:1: `mockConsoleLog`/`mockConsoleError` →
`captureConsole(['error'])`, `mockProcessStdout`/`mockProcessStderr` →
`captureStream(['stderr'])`.
- Bump `@doist/cli-core` 0.23.0 → 0.24.0, which ships these helpers and
types the capture spies as `MockInstance` so `.mock.calls` stays usable
without per-call annotations.

39 test files re-pointed; 2 local helper files deleted. No
source/runtime files changed. Skipped `buildTokenStore`/account fixtures
— todoist's auth tests are module-level `vi.fn()` interaction mocks, the
wrong shape for cli-core's stateful store fake.

## Test plan
- [x] `npm run type-check`
- [x] `npm run check` (oxlint + oxfmt)
- [x] `npm test` — 1663 tests pass (66 files), against published 0.24.0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [lefthook](https://redirect.github.com/evilmartians/lefthook) |
[`2.1.6` →
`2.1.8`](https://renovatebot.com/diffs/npm/lefthook/2.1.6/2.1.8) |
![age](https://developer.mend.io/api/mc/badges/age/npm/lefthook/2.1.8?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lefthook/2.1.6/2.1.8?slim=true)
|

---

### Release Notes

<details>
<summary>evilmartians/lefthook (lefthook)</summary>

###
[`v2.1.8`](https://redirect.github.com/evilmartians/lefthook/blob/HEAD/CHANGELOG.md#218-2026-05-19)

[Compare
Source](https://redirect.github.com/evilmartians/lefthook/compare/v2.1.7...v2.1.8)

- fix: do not warn if local hooks path is equal to default hooks path
([#&#8203;1421](https://redirect.github.com/evilmartians/lefthook/pull/1421))
by [@&#8203;mrexox]()

###
[`v2.1.7`](https://redirect.github.com/evilmartians/lefthook/blob/HEAD/CHANGELOG.md#217-2026-05-19)

[Compare
Source](https://redirect.github.com/evilmartians/lefthook/compare/v2.1.6...v2.1.7)

- fix: use contrast colors
([#&#8203;1420](https://redirect.github.com/evilmartians/lefthook/pull/1420))
by [@&#8203;mrexox]()
- fix: apply stage\_fixed only if it is safe
([#&#8203;1418](https://redirect.github.com/evilmartians/lefthook/pull/1418))
by [@&#8203;mrexox]()
- fix: try to always restore unstaged changes
([#&#8203;1417](https://redirect.github.com/evilmartians/lefthook/pull/1417))
by [@&#8203;mrexox]()
- fix: always restore unstaged changes
([#&#8203;1416](https://redirect.github.com/evilmartians/lefthook/pull/1416))
by [@&#8203;mrexox]()
- refactor: add new logger without a global state
([#&#8203;1385](https://redirect.github.com/evilmartians/lefthook/pull/1385))
by [@&#8203;mrexox]()
- fix: linter, sacrifice optimization for readability by
[@&#8203;mrexox]()
- fix: separate fallback push branch from pathspecs
([#&#8203;1396](https://redirect.github.com/evilmartians/lefthook/pull/1396))
by [@&#8203;lawrence3699]()

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [marked](https://marked.js.org)
([source](https://redirect.github.com/markedjs/marked)) | [`18.0.3` →
`18.0.4`](https://renovatebot.com/diffs/npm/marked/18.0.3/18.0.4) |
![age](https://developer.mend.io/api/mc/badges/age/npm/marked/18.0.4?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/marked/18.0.3/18.0.4?slim=true)
|

---

### Release Notes

<details>
<summary>markedjs/marked (marked)</summary>

###
[`v18.0.4`](https://redirect.github.com/markedjs/marked/releases/tag/v18.0.4)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v18.0.3...v18.0.4)

##### Bug Fixes

- cache list indentation regexes
([#&#8203;3969](https://redirect.github.com/markedjs/marked/issues/3969))
([a37983f](https://redirect.github.com/markedjs/marked/commit/a37983f188d697fe98d350554dc95c49eaac6edd))
- fix cli not reading stdin
([#&#8203;3967](https://redirect.github.com/markedjs/marked/issues/3967))
([11adb69](https://redirect.github.com/markedjs/marked/commit/11adb697eeee2b0fa6da3a38d5146626347592dc))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## [1.69.1](v1.69.0...v1.69.1) (2026-05-25)

### Bug Fixes

* **deps:** update dependency marked to v18.0.4 ([#364](#364)) ([34793c1](34793c1))
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [vitest](https://vitest.dev)
([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest))
| [`4.1.6` →
`4.1.7`](https://renovatebot.com/diffs/npm/vitest/4.1.6/4.1.7) |
![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/4.1.7?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/4.1.6/4.1.7?slim=true)
|

---

### Release Notes

<details>
<summary>vitest-dev/vitest (vitest)</summary>

###
[`v4.1.7`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v4.1.7)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.6...v4.1.7)

#####    🐞 Bug Fixes

- **runner**: Limit concurrency per task branch in addition to per leaf
callbacks (backport)  -  by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[#&#8203;10384](https://redirect.github.com/vitest-dev/vitest/issues/10384)
[<samp>(4f0f2)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/4f0f2a1ee)

#####     [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.6...v4.1.7)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
|
[@types/node](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node)
([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node))
| [`25.8.0` →
`25.9.1`](https://renovatebot.com/diffs/npm/@types%2fnode/25.8.0/25.9.1)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/25.9.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/25.8.0/25.9.1?slim=true)
|

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oxfmt](https://oxc.rs/docs/guide/usage/formatter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt))
| [`0.50.0` →
`0.51.0`](https://renovatebot.com/diffs/npm/oxfmt/0.50.0/0.51.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxfmt/0.51.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxfmt/0.50.0/0.51.0?slim=true)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxfmt)</summary>

###
[`v0.51.0`](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.50.0...oxfmt_v0.51.0)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.50.0...oxfmt_v0.51.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oxlint](https://oxc.rs/docs/guide/usage/linter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint))
| [`1.65.0` →
`1.66.0`](https://renovatebot.com/diffs/npm/oxlint/1.65.0/1.66.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxlint/1.66.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxlint/1.65.0/1.66.0?slim=true)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxlint)</summary>

###
[`v1.66.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#1660---2026-05-18)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v1.65.0...oxlint_v1.66.0)

##### 🚀 Features

-
[`0440b0f`](https://redirect.github.com/oxc-project/oxc/commit/0440b0f)
linter/eslint: Implement `id-match` rule
([#&#8203;22379](https://redirect.github.com/oxc-project/oxc/issues/22379))
(Vladislav Sayapin)
-
[`65bf119`](https://redirect.github.com/oxc-project/oxc/commit/65bf119)
linter: Implement react no-object-type-as-default-prop
([#&#8203;22481](https://redirect.github.com/oxc-project/oxc/issues/22481))
(uhyo)
-
[`2a6ddce`](https://redirect.github.com/oxc-project/oxc/commit/2a6ddce)
linter/eslint: Implement `no-implied-eval` rule
([#&#8203;22391](https://redirect.github.com/oxc-project/oxc/issues/22391))
(Vladislav Sayapin)
-
[`625758a`](https://redirect.github.com/oxc-project/oxc/commit/625758a)
linter/vitest: Implement padding-around-after-all-blocks rule
([#&#8203;21788](https://redirect.github.com/oxc-project/oxc/issues/21788))
(kapobajza)
-
[`37680b0`](https://redirect.github.com/oxc-project/oxc/commit/37680b0)
linter: Implement react no-unstable-nested-components
([#&#8203;22248](https://redirect.github.com/oxc-project/oxc/issues/22248))
(Jovi De Croock)
-
[`d8d9c74`](https://redirect.github.com/oxc-project/oxc/commit/d8d9c74)
linter: Implement import/newline-after-import rule
([#&#8203;19142](https://redirect.github.com/oxc-project/oxc/issues/19142))
(Ryuya Yanagi)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [date-fns](https://redirect.github.com/date-fns/date-fns) | [`4.1.0` →
`4.2.1`](https://renovatebot.com/diffs/npm/date-fns/4.1.0/4.2.1) |
![age](https://developer.mend.io/api/mc/badges/age/npm/date-fns/4.2.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/date-fns/4.1.0/4.2.1?slim=true)
|

---

### Release Notes

<details>
<summary>date-fns/date-fns (date-fns)</summary>

###
[`v4.2.1`](https://redirect.github.com/date-fns/date-fns/releases/tag/v4.2.1)

[Compare
Source](https://redirect.github.com/date-fns/date-fns/compare/v4.2.0...v4.2.1)

##### Fixed

- Fixed type definitions missing in v4.2.0 due to TypeScript
misconfiguration.

###
[`v4.2.0`](https://redirect.github.com/date-fns/date-fns/blob/HEAD/CHANGELOG.md#v420---2026-05-18)

[Compare
Source](https://redirect.github.com/date-fns/date-fns/compare/v4.1.0...v4.2.0)

This is a minor release in all senses, it only includes documentation
updates (first of many) that points to the new [You Don't Need
date-fns\*](https://date-fns.org/you-dont-need-date-fns) page.

\* Not really

##### Changed

- Added Temporal API references to the JSDoc annotations of `add`,
`addBusinessDays`, and `addDays`.

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## [1.69.2](v1.69.1...v1.69.2) (2026-05-26)

### Bug Fixes

* **deps:** update dependency date-fns to v4.2.1 ([#369](#369)) ([55f218a](55f218a))
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [date-fns](https://redirect.github.com/date-fns/date-fns) | [`4.2.1` →
`4.3.0`](https://renovatebot.com/diffs/npm/date-fns/4.2.1/4.3.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/date-fns/4.3.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/date-fns/4.2.1/4.3.0?slim=true)
|

---

### Release Notes

<details>
<summary>date-fns/date-fns (date-fns)</summary>

###
[`v4.3.0`](https://redirect.github.com/date-fns/date-fns/releases/tag/v4.3.0)

[Compare
Source](https://redirect.github.com/date-fns/date-fns/compare/v4.2.1...v4.3.0)

Kudos to [@&#8203;ImRodry](https://redirect.github.com/ImRodry) and
[@&#8203;puneetdixit200](https://redirect.github.com/puneetdixit200) for
their contributions.

##### Fixed

- Fixed missing modularized optimization fallback ([for Next.js and
others](https://x.com/kossnocorp/status/1731181274579325260)). See
[#&#8203;4193](https://x.com/kossnocorp/status/1731181274579325260).

- Fixed `pt` locale first day of week to be Sunday. See
[#&#8203;4195](https://redirect.github.com/date-fns/date-fns/pull/4195)
by [@&#8203;ImRodry](https://redirect.github.com/ImRodry).

- Fixed `zh-CN`, `zh-HK`, and `zh-TW` locale month parsing for October,
November, and December. See
[#&#8203;4194](https://redirect.github.com/date-fns/date-fns/pull/4194)
by [@&#8203;puneetdixit200](https://redirect.github.com/puneetdixit200).

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## [1.69.3](v1.69.2...v1.69.3) (2026-05-28)

### Bug Fixes

* **deps:** update dependency date-fns to v4.3.0 ([#371](#371)) ([76b0c57](76b0c57))
## What

Adds `td project share <project-ref> <email>` to invite a collaborator
to a project — closes the gap alongside the existing `project join` and
`project collaborators` commands.

Closes #372.

```
td project share <project-ref> <email> [--role guest|member|admin] [--message <msg>] [--auto-invite] [--json] [--dry-run]
```

## Behaviour

- **Personal / shared projects** — shares via the `share_project` sync
command. `--role` / `--auto-invite` don't apply and are ignored with a
warning.
- **Workspace projects** — `--role guest|member|admin` (default
`member`) maps to the workspace role. If the email isn't already a
workspace member, the command errors with a hint, unless `--auto-invite`
is passed — which invites them to the workspace first (via
`inviteWorkspaceUsers`) and then shares.
- `--message` attaches an optional invitation message.
- `--dry-run` previews (including whether an auto-invite would fire)
without mutating; `--json` outputs the result.

## Notes

- Inviting is only available through the Sync API `share_project`
command (there's no REST endpoint), so this adds a `shareProject` sync
wrapper in `lib/api/projects-sync.ts`.
- Role vocabulary is the real workspace roles
(`guest`/`member`/`admin`), not the `viewer`/`editor` in the original
issue text.
- Skill content + `SKILL.md` updated and in sync.
- Share tests live in a new `project.share.test.ts`, and the shared
`createProjectProgram` test helper was extracted for reuse.

## Verification

- `npm run type-check` ✅
- `npm run check` (lint + format) ✅
- `npm run check:skill-sync` ✅
- `npm test` — full suite passes (1672)
## [1.70.0](v1.69.3...v1.70.0) (2026-05-29)

### Features

* **project:** add `project share` to invite a collaborator ([#373](#373)) ([514d0fd](514d0fd))
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oxfmt](https://oxc.rs/docs/guide/usage/formatter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt))
| [`0.51.0` →
`0.52.0`](https://renovatebot.com/diffs/npm/oxfmt/0.51.0/0.52.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxfmt/0.52.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxfmt/0.51.0/0.52.0?slim=true)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxfmt)</summary>

###
[`v0.52.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxfmt/CHANGELOG.md#0520---2026-05-26)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.51.0...oxfmt_v0.52.0)

##### 🚀 Features

-
[`16b8058`](https://redirect.github.com/oxc-project/oxc/commit/16b8058)
oxfmt: Support `vite-plus/resolveConfig` for vite.config.ts
([#&#8203;22454](https://redirect.github.com/oxc-project/oxc/issues/22454))
(leaysgur)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMDIuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIwNi4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oxlint](https://oxc.rs/docs/guide/usage/linter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint))
| [`1.66.0` →
`1.67.0`](https://renovatebot.com/diffs/npm/oxlint/1.66.0/1.67.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxlint/1.67.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxlint/1.66.0/1.67.0?slim=true)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxlint)</summary>

###
[`v1.67.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#1670---2026-05-26)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v1.66.0...oxlint_v1.67.0)

##### 🚀 Features

-
[`b84941e`](https://redirect.github.com/oxc-project/oxc/commit/b84941e)
linter/vue: Implement no-expose-after-await rule
([#&#8203;22675](https://redirect.github.com/oxc-project/oxc/issues/22675))
(bab)
-
[`98b98c1`](https://redirect.github.com/oxc-project/oxc/commit/98b98c1)
linter/vue: Implement no-computed-properties-in-data rule
([#&#8203;22674](https://redirect.github.com/oxc-project/oxc/issues/22674))
(bab)
-
[`2d4c919`](https://redirect.github.com/oxc-project/oxc/commit/2d4c919)
oxlint: Support `vite-plus/resolveConfig` for vite.config.ts
([#&#8203;22456](https://redirect.github.com/oxc-project/oxc/issues/22456))
(leaysgur)
-
[`2a60012`](https://redirect.github.com/oxc-project/oxc/commit/2a60012)
linter/vue: Implement require-render-return rule
([#&#8203;22613](https://redirect.github.com/oxc-project/oxc/issues/22613))
(bab)
-
[`9f227fd`](https://redirect.github.com/oxc-project/oxc/commit/9f227fd)
linter/vue: Implement no-deprecated-props-default-this rule
([#&#8203;21892](https://redirect.github.com/oxc-project/oxc/issues/21892))
(bab)
-
[`87f065e`](https://redirect.github.com/oxc-project/oxc/commit/87f065e)
linter/vue: Implement return-in-emits-validator rule
([#&#8203;21935](https://redirect.github.com/oxc-project/oxc/issues/21935))
(bab)
-
[`ea0380c`](https://redirect.github.com/oxc-project/oxc/commit/ea0380c)
linter/unicorn: Implement `import-style` rule
([#&#8203;22173](https://redirect.github.com/oxc-project/oxc/issues/22173))
(Hao Chen)
-
[`dde40fe`](https://redirect.github.com/oxc-project/oxc/commit/dde40fe)
linter/vue: Implement no-watch-after-await rule
([#&#8203;22006](https://redirect.github.com/oxc-project/oxc/issues/22006))
(bab)
-
[`a735eb0`](https://redirect.github.com/oxc-project/oxc/commit/a735eb0)
linter/vue: Implement valid-next-tick rule
([#&#8203;22531](https://redirect.github.com/oxc-project/oxc/issues/22531))
(bab)
-
[`6dc615d`](https://redirect.github.com/oxc-project/oxc/commit/6dc615d)
linter/vue: Implement no-shared-component-data rule
([#&#8203;21842](https://redirect.github.com/oxc-project/oxc/issues/21842))
(bab)
-
[`a656418`](https://redirect.github.com/oxc-project/oxc/commit/a656418)
linter/vue: Implement valid-define-options rule
([#&#8203;22107](https://redirect.github.com/oxc-project/oxc/issues/22107))
(bab)
-
[`bb6f1b2`](https://redirect.github.com/oxc-project/oxc/commit/bb6f1b2)
linter/vue: Implement require-slots-as-functions rule
([#&#8203;22244](https://redirect.github.com/oxc-project/oxc/issues/22244))
(bab)
-
[`5fa4774`](https://redirect.github.com/oxc-project/oxc/commit/5fa4774)
linter/n: Implement `callback-return` rule
([#&#8203;22470](https://redirect.github.com/oxc-project/oxc/issues/22470))
(Mikhail Baev)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMDIuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIwNi4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## What

Adds a `--no-browser-open` flag to `td auth login`. With it, the OAuth
flow prints the authorization URL for manual copy-paste instead of
automatically opening a browser.

```
td auth login --no-browser-open
```

## Why

Useful on headless or remote hosts, in SSH sessions, or any time you'd
rather not have the desktop browser hijacked. cli-core already
auto-skips the spawn on detected headless/WSL environments; this flag
forces the skip everywhere.

## How

cli-core surfaces the authorize URL before its `openBrowser` hook fires,
so skipping the spawn still leaves a usable login — the printed URL is
the path through. cli-core's `openBrowser` hook isn't handed the parsed
flags, so the option is read off the command at call time (commander
negatable `--no-browser-open` → `browserOpen`, default `true`).

## Tests

- Added two tests: opens the browser by default, skips when the flag is
set.
- SKILL content updated and regenerated via `sync:skill`.
- `type-check`, `check` (oxlint + oxfmt), and the auth login suite all
pass.
## [1.71.0](v1.70.0...v1.71.0) (2026-06-02)

### Features

* **auth:** add `--no-browser-open` to `auth login` ([#376](#376)) ([90ee8ec](90ee8ec))
## What

Expand `td apps view <ref>` so that when an integration ships **UI
extensions**, the view:

- Lists each UI extension as `<name> (<type>[: <sub-type>])`, where type
is `context-menu` / `composer` / `settings` and sub-type is the
`context-menu` context (`project`/`task`) or `composer` location
(`task`/`comment`). Settings extensions have no sub-type.
- Prints the **installable URL**
(`https://app.todoist.com/app/install/<distribution_token>`) — the link
an integration owner shares so others can install it. This is required
for any integration with UI extensions.

When an app has no UI extensions, neither the section nor the install
URL is shown.

## Why

The view previously omitted the install URL entirely, which is required
to distribute an integration that has UI extensions. The SDK already
exposes `getUiExtensionsForApp` (previously unused) to detect them; the
install URL mirrors how `todoist-web` builds it
(`<origin>/app/install/<distribution_token>`).

## Distribution token reclassified as non-secret

The distribution token is the basis of a **shareable install link** by
design, so it is now:
- always fetched (no longer gated behind `--include-secrets`)
- surfaced via the `Install URL` line / `installUrl` JSON field by
default

The genuinely sensitive credentials — client secret, verification token,
test token — remain hidden by default.

## Output

`--json` / `--ndjson` now always carry `uiExtensions`,
`distributionToken`, and `installUrl` (`null` when the app has no UI
extensions).

## Testing

- `npm run type-check` ✅
- Full suite: 1686 tests ✅ (new tests cover with/without UI extensions,
sub-type formatting, and JSON payload)
- `npm run check` (lint + format) ✅
- Skill content updated + `npm run sync:skill`
## [1.72.0](v1.71.0...v1.72.0) (2026-06-02)

### Features

* **apps:** show UI extensions and install URL in `apps view` ([#377](#377)) ([53d9fe6](53d9fe6))
Closes #362.

## What

Replace the hand-rolled `vi.fn()` token-store interaction mocks in
`src/commands/auth/auth.test.ts` with cli-core's stateful
`buildTokenStore` fake from `@doist/cli-core/testing` — the part PR #361
deliberately scoped out.

## How

- Add a `makeTodoistStore` helper that wraps
`buildTokenStore<TodoistAccount>` and bolts on the keyring-only methods
(`getLastStorageResult` / `getLastClearResult` / `activeAccount`) that
live on `KeyringTokenStore` but not `TokenStore`, so the result
satisfies `TodoistTokenStore`.
- A `vi.hoisted` holder + `useStore()` installer feeds a per-test store
into the `createTodoistTokenStore` mock (the factory is called eagerly
at register time, so the store is installed before `createProgram()`).
- Assertions move from the bare mocks to the harness: `state.entries` /
`clearSpy` / `activeSpy`.
- The persisted-account snapshot block converts to a
`buildTokenStore`-backed store too, seeded with a **bundle** (status
reads `activeBundle()` first and treats a null bundle as logged-out, so
a plain token wouldn't resolve that path).
- logout / token-view ref-resolution tests use the shared ingen fixtures
(`alanGrant`). No `matchAccount` override needed — todoist resolves by
id/email/label, cli-core's default.

## Notes

- Test-only refactor; no product behaviour change.
- Net: deletes the six module-level `vi.fn()`s + stub factory, the
bespoke snapshot-store literal, and three reset `beforeEach` blocks.

## Verification

- `npm run type-check` — clean
- `npm test` — 1688 passed
- `npm run check` — clean
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [lefthook](https://redirect.github.com/evilmartians/lefthook) |
[`2.1.8` →
`2.1.9`](https://renovatebot.com/diffs/npm/lefthook/2.1.8/2.1.9) |
![age](https://developer.mend.io/api/mc/badges/age/npm/lefthook/2.1.9?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lefthook/2.1.8/2.1.9?slim=true)
|

---

### Release Notes

<details>
<summary>evilmartians/lefthook (lefthook)</summary>

###
[`v2.1.9`](https://redirect.github.com/evilmartians/lefthook/blob/HEAD/CHANGELOG.md#219-2026-05-29)

[Compare
Source](https://redirect.github.com/evilmartians/lefthook/compare/v2.1.8...v2.1.9)

- fix: update hooks path after resetting
([#&#8203;1431](https://redirect.github.com/evilmartians/lefthook/pull/1431))
by [@&#8203;mrexox]()
- deps: May 2026
([#&#8203;1415](https://redirect.github.com/evilmartians/lefthook/pull/1415))
by [@&#8203;mrexox]()

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMDkuNCIsInVwZGF0ZWRJblZlciI6IjQzLjIwOS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [date-fns](https://redirect.github.com/date-fns/date-fns) | [`4.3.0` →
`4.4.0`](https://renovatebot.com/diffs/npm/date-fns/4.3.0/4.4.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/date-fns/4.4.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/date-fns/4.3.0/4.4.0?slim=true)
|

---

### Release Notes

<details>
<summary>date-fns/date-fns (date-fns)</summary>

###
[`v4.4.0`](https://redirect.github.com/date-fns/date-fns/releases/tag/v4.4.0)

[Compare
Source](https://redirect.github.com/date-fns/date-fns/compare/v4.3.0...v4.4.0)

This release revisits the approach to CDN usage and introduces a new
package, `@date-fns/cdn` and deprecates the `date-fns` CDN scripts. It
allowed reducing the zipped package size from `5.83 MB` down to `3.96
MB` without introducing any breaking changes.

In `v5.0.0-alpha.0` where CDN scripts are completely removed from
`date-fns` the change is more significant and brings the zipped package
size down to `2.89 MB`.

It is just the first step in optimizing the package size. Expect further
size reduction in the future v4 and v5 versions.

##### Changed

- **DEPRECATED**: The `date-fns` CDN scripts are now deprecated and will
be removed in the next major release. Please switch to the new
`@date-fns/cdn` package for CDN usage.

- Removed CDN source maps to reduce the package size. If you rely on
them, please switch to the new `@date-fns/cdn` package that still
includes them.

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMDkuNCIsInVwZGF0ZWRJblZlciI6IjQzLjIwOS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## [1.72.1](v1.72.0...v1.72.1) (2026-06-04)

### Bug Fixes

* **deps:** update dependency date-fns to v4.4.0 ([#381](#381)) ([bdcbe71](bdcbe71))
## Overview

Adds `td apps delete <ref>` to remove a registered developer app,
resolved by name, id:N, or raw numeric id. Requires `--yes` to actually
delete; without it the command prints a preview and makes no API call
(same convention as `td folder delete` / `td workspace delete`).
`--dry-run` prints the standard dry-run preview.

Wires the scope-error hint and spinner message for deleteApp (and the
previously-missing updateApp), and documents the command in the skill.

## Reference

- Closes #383

## Test Plan

- `npm run dev`
- `node dist/index.js auth login --additional-scopes=app-management`
- Create a test app (either via the UI or via command line, doesn't
matter)
- `node dist/index.js apps list` (you'll see your app)
- `node dist/index.js apps delete id:XXXX` // <--- use the app id
instead of "XXXX"
- [ ] Confirm that this is just a dry-run (would need `--yes` to
actually delete)
- `node dist/index.js apps delete id:XXXX --dry-run`
- [ ] Confirm that this is just a dry-run (would need `--yes` to
actually delete)
- `node dist/index.js apps delete "Test"` (or whatever would match your
test app name)
- [ ] Confirm that this is just a dry-run (would need `--yes` to
actually delete)
- `node dist/index.js apps delete id:9999` // <--- fake app id that
doesn't existing in your account
- [ ] Confirm you get an `APP_NOT_FOUND` error
- `node dist/index.js apps delete id:XXXX --yes` // <--- this will
actually delete your test app, finally!
- [ ] Confirm the app is deleted (i.e. via the UI or via command line,
doesn't matter)

## Demo

### List

```
node dist/index.js apps list
```

```
[...]
Test (id:109707)
   Client ID: 9b6298a2f93e448e8734ea4a339ff71a
   (no description)
```

### Delete via app id

```
node dist/index.js apps delete id:109707
```

```
Would delete app: Test (id:109707)
Use --yes to confirm.
```

### Delete via app id + dry-run

```
node dist/index.js apps delete id:109707 --dry-run
```

```
[dry-run] Would delete app:
  App: Test
  ID: 109707
```

### Delete via app name

```
node dist/index.js apps delete "Test"
```

```
Would delete app: Test (id:109707)
Use --yes to confirm.
```

### Delete via non-existing app id

```
node dist/index.js apps delete id:9999
```

```
Error: APP_NOT_FOUND
App "id:9999" not found.
```

### Delete via app id + yes

```
node dist/index.js apps delete id:109707 --yes
```

```
Deleted: Test (id:109707)
```

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
## [1.73.0](v1.72.1...v1.73.0) (2026-06-05)

### Features

* **apps:** Add delete command ([#385](#385)) ([480f41b](480f41b)), closes [#383](#383)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [vitest](https://vitest.dev)
([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest))
| [`4.1.7` →
`4.1.8`](https://renovatebot.com/diffs/npm/vitest/4.1.7/4.1.8) |
![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/4.1.8?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/4.1.7/4.1.8?slim=true)
|

---

### Release Notes

<details>
<summary>vitest-dev/vitest (vitest)</summary>

###
[`v4.1.8`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v4.1.8)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8)

#####    🐞 Bug Fixes

- **browser**:
- Disable client `cdp` API when `allowWrite/allowExec: false` \[backport
to v4]  -  by [@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa)
and **Codex** in
[#&#8203;10450](https://redirect.github.com/vitest-dev/vitest/issues/10450)
[<samp>(e4067)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/e4067b3b1)
- Remove orphaned Playwright route when same module is mocked via
multiple ids \[backport to v4]  -  by
[@&#8203;toxik](https://redirect.github.com/toxik) and
[@&#8203;Zelys-DFKH](https://redirect.github.com/Zelys-DFKH) in
[#&#8203;10474](https://redirect.github.com/vitest-dev/vitest/issues/10474)
[<samp>(675b4)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/675b4343f)

#####     [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.7...v4.1.8)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMDkuNCIsInVwZGF0ZWRJblZlciI6IjQzLjIwOS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Bump to the SDK release that pins undici to 7.24.8 and avoids the Node 26 regression seen with fresh installs.
doist-release-bot Bot and others added 28 commits July 29, 2026 06:47
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
|
[@semantic-release/git](https://redirect.github.com/semantic-release/git)
| [`11.0.0` →
`11.0.1`](https://renovatebot.com/diffs/npm/@semantic-release%2fgit/11.0.0/11.0.1)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@semantic-release%2fgit/11.0.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@semantic-release%2fgit/11.0.0/11.0.1?slim=true)
|

---

### Release Notes

<details>
<summary>semantic-release/git (@&#8203;semantic-release/git)</summary>

###
[`v11.0.1`](https://redirect.github.com/semantic-release/git/releases/tag/v11.0.1)

[Compare
Source](https://redirect.github.com/semantic-release/git/compare/v11.0.0...v11.0.1)

##### Bug Fixes

- **deps:** update dependency execa to v10
([#&#8203;564](https://redirect.github.com/semantic-release/git/issues/564))
([b39d5c6](https://redirect.github.com/semantic-release/git/commit/b39d5c6adcd2eb1f921481d8cbb3d605e629b56a))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Closes #424

## Summary

- Upgrade to `@doist/cli-core@1.1.0`, which owns the keyring storage
policy.
- Default Todoist CLI credential writes to strict system storage: an
unavailable credential manager fails the write without creating a
plaintext config entry.
- Keep `--credential-store=plaintext` as the explicit opt-in for both
OAuth and manual-token authentication; cli-core returns a warning for
every successful plaintext credential write.

## Usage

Default, system-only storage:

```sh
td auth login
td auth token "YOUR_TOKEN"
```

Explicit plaintext storage:

```sh
td auth login --credential-store=plaintext
td auth token "YOUR_TOKEN" --credential-store=plaintext
# Warning: credential stored as plaintext in ~/.config/todoist-cli/config.json
```

## Verification

- Clean dependency install: `npm ci`
- `npm run build`
- `npm run type-check`
- Full test suite: 66 files, 1,740 tests
- `npm run check`
- Verified `td auth login --help` and `td auth token --help` show the
new flag
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [chalk](https://redirect.github.com/chalk/chalk) | [`5.6.2` →
`6.0.0`](https://renovatebot.com/diffs/npm/chalk/5.6.2/6.0.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/chalk/6.0.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/chalk/5.6.2/6.0.0?slim=true)
|

---

### Release Notes

<details>
<summary>chalk/chalk (chalk)</summary>

###
[`v6.0.0`](https://redirect.github.com/chalk/chalk/compare/v5.6.2...661317e6f91fe7c90306c2c48ea9354562ee9146)

[Compare
Source](https://redirect.github.com/chalk/chalk/compare/v5.6.2...v6.0.0)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zLjIiLCJ1cGRhdGVkSW5WZXIiOiI0NC4zLjIiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oxfmt](https://oxc.rs/docs/guide/usage/formatter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt))
| [`0.60.0` →
`0.61.0`](https://renovatebot.com/diffs/npm/oxfmt/0.60.0/0.61.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxfmt/0.61.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxfmt/0.60.0/0.61.0?slim=true)
|
| [oxlint](https://oxc.rs/docs/guide/usage/linter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint))
| [`1.75.0` →
`1.76.0`](https://renovatebot.com/diffs/npm/oxlint/1.75.0/1.76.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxlint/1.76.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxlint/1.75.0/1.76.0?slim=true)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxfmt)</summary>

###
[`v0.61.0`](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.60.0...oxfmt_v0.61.0)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.60.0...oxfmt_v0.61.0)

</details>

<details>
<summary>oxc-project/oxc (oxlint)</summary>

###
[`v1.76.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#1760---2026-07-27)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v1.75.0...oxlint_v1.76.0)

##### 🚀 Features

-
[`8d31dfa`](https://redirect.github.com/oxc-project/oxc/commit/8d31dfa)
linter: Verify eslint/no-restricted-globals config schema
([#&#8203;24598](https://redirect.github.com/oxc-project/oxc/issues/24598))
(vigneshwar)
-
[`7069621`](https://redirect.github.com/oxc-project/oxc/commit/7069621)
linter: Verify jest/vitest prefer-lowercase-title config schema
([#&#8203;24724](https://redirect.github.com/oxc-project/oxc/issues/24724))
(Bartok)
-
[`016cf2a`](https://redirect.github.com/oxc-project/oxc/commit/016cf2a)
linter/oxc: Add bad-match-all-arg rule
([#&#8203;24900](https://redirect.github.com/oxc-project/oxc/issues/24900))
(camc314)
-
[`cdc941e`](https://redirect.github.com/oxc-project/oxc/commit/cdc941e)
linter/n: Implement `exports-style` rule
([#&#8203;24087](https://redirect.github.com/oxc-project/oxc/issues/24087))
(Mikhail Baev)
-
[`1ad6f6c`](https://redirect.github.com/oxc-project/oxc/commit/1ad6f6c)
linter/eslint: Implement `id-denylist` rule
([#&#8203;24632](https://redirect.github.com/oxc-project/oxc/issues/24632))
(Mikhail Baev)

##### 📚 Documentation

-
[`3ff2e0e`](https://redirect.github.com/oxc-project/oxc/commit/3ff2e0e)
linter: Clarify config extends types
([#&#8203;24936](https://redirect.github.com/oxc-project/oxc/issues/24936))
(Boshen)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zLjIiLCJ1cGRhdGVkSW5WZXIiOiI0NC4zLjIiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@doist/todoist-sdk](https://doist.github.io/todoist-sdk-typescript/)
([source](https://redirect.github.com/Doist/todoist-sdk-typescript)) |
[`12.0.0` →
`13.0.0`](https://renovatebot.com/diffs/npm/@doist%2ftodoist-sdk/12.0.0/13.0.0)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@doist%2ftodoist-sdk/13.0.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@doist%2ftodoist-sdk/12.0.0/13.0.0?slim=true)
|

---

### Release Notes

<details>
<summary>Doist/todoist-sdk-typescript
(@&#8203;doist/todoist-sdk)</summary>

###
[`v13.0.0`](https://redirect.github.com/Doist/todoist-sdk-typescript/blob/HEAD/CHANGELOG.md#1300-2026-07-27)

[Compare
Source](https://redirect.github.com/Doist/todoist-sdk-typescript/compare/v12.0.0...v13.0.0)

##### ⚠ BREAKING CHANGES

- **workspaces:** remove invitation `isExistingUser`
([#&#8203;650](https://redirect.github.com/Doist/todoist-sdk-typescript/issues/650))

##### Bug Fixes

- **workspaces:** remove invitation `isExistingUser`
([#&#8203;650](https://redirect.github.com/Doist/todoist-sdk-typescript/issues/650))
([1eb8205](https://redirect.github.com/Doist/todoist-sdk-typescript/commit/1eb8205365ea463ee54ab3e75ec98ef5be44a083))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zLjIiLCJ1cGRhdGVkSW5WZXIiOiI0NC4zLjIiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Removes the package-version metadata from the generated skill and
eliminates release-time regeneration.

The committed SKILL.md remains synchronized when the skill content
changes.

- Closes #458 
- See also:
#275 (comment)
## Summary

- validate completed-task date formats and the API three-month range
limit before making a request
- return actionable errors for unsupported ranges
- preserve detailed API error messages when available
- update command help and agent skill documentation

Closes #465

## Verification

- npm test
- npm run type-check
- npm run check
- npm run check:skill-sync
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.1.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md">js-yaml's
changelog</a>.</em></p>
<blockquote>
<h2>4.3.1 - 2026-07-31</h2>
<h3>Security</h3>
<ul>
<li>[backport] Remove quadratic complexity from <code>!!omap</code>
duplicate key detection.</li>
</ul>
<h2>4.3.0 - 2026-06-27</h2>
<h3>Added</h3>
<ul>
<li>[backport] Added <code>maxTotalMergeKeys</code> (10000) loader
option to limit the total number of
keys processed by YAML merge (<code>&lt;&lt;</code>) across one
<code>load()</code> / <code>loadAll()</code> call.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Restore umd builds back to es5.</li>
</ul>
<h3>Removed</h3>
<ul>
<li>[backport] <code>maxMergeSeqLength</code> replaced with
<code>maxTotalMergeKeys</code> for limiting YAML merge
processing.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nodeca/js-yaml/commit/86e91b815b8794c3c73a179c1770871e37ec2df8"><code>86e91b8</code></a>
4.3.1 released</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/c3cc4b0bb9ddb9af2dd9b61e0d56f5ce7983cd4a"><code>c3cc4b0</code></a>
Backport quadratic complexity fix for !!omap</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/33d05b5d29a8c21360f620f7e1c1706e24522eda"><code>33d05b5</code></a>
4.3.0 released</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/663bfab6db2b4a146a9366fd685f069345be4ddb"><code>663bfab</code></a>
Drop demo publish, to not override new v5 one.</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/1cb8c7b94bf75e15116869c1c0482dcb22785986"><code>1cb8c7b</code></a>
Add v4-legacy tag for publish</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/02f27afad532763263cd2b6be35c24ee8e1f6157"><code>02f27af</code></a>
Restore umd builds back to es5</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/8be84edaf15e7c394fa3b813179d1bcc280e87fb"><code>8be84ed</code></a>
Fix es5 compatibility</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/59423c6f8cdc78742ac00e25a4dd39ef16b702e4"><code>59423c6</code></a>
Replace <code>maxMergeSeqLength</code> option with
<code>maxTotalMergeKeys</code> (more robust). Ba...</li>
<li><a
href="https://github.com/nodeca/js-yaml/commit/6842ef6a02df01ca7282ea01dc3c70787710c05d"><code>6842ef6</code></a>
doc polish</li>
<li>See full diff in <a
href="https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=js-yaml&package-manager=npm_and_yarn&previous-version=4.2.0&new-version=4.3.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/Doist/todoist-cli/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@doist/todoist-sdk](https://doist.github.io/todoist-sdk-typescript/)
([source](https://redirect.github.com/Doist/todoist-sdk-typescript)) |
[`13.0.0` →
`13.0.2`](https://renovatebot.com/diffs/npm/@doist%2ftodoist-sdk/13.0.0/13.0.2)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@doist%2ftodoist-sdk/13.0.2?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@doist%2ftodoist-sdk/13.0.0/13.0.2?slim=true)
|

---

### Release Notes

<details>
<summary>Doist/todoist-sdk-typescript
(@&#8203;doist/todoist-sdk)</summary>

###
[`v13.0.2`](https://redirect.github.com/Doist/todoist-sdk-typescript/blob/HEAD/CHANGELOG.md#1302-2026-08-04)

[Compare
Source](https://redirect.github.com/Doist/todoist-sdk-typescript/compare/v13.0.1...v13.0.2)

##### Bug Fixes

- allow omitted workspace insight folder ID
([#&#8203;655](https://redirect.github.com/Doist/todoist-sdk-typescript/issues/655))
([e44e38a](https://redirect.github.com/Doist/todoist-sdk-typescript/commit/e44e38afcbba0b610a781ed85295eba531f5ed2a))
- serialize task IDs as comma-separated query parameter
([#&#8203;656](https://redirect.github.com/Doist/todoist-sdk-typescript/issues/656))
([2a31bd6](https://redirect.github.com/Doist/todoist-sdk-typescript/commit/2a31bd61266036bd420d422f6f34b3b68da8707f))

###
[`v13.0.1`](https://redirect.github.com/Doist/todoist-sdk-typescript/blob/HEAD/CHANGELOG.md#1301-2026-08-03)

[Compare
Source](https://redirect.github.com/Doist/todoist-sdk-typescript/compare/v13.0.0...v13.0.1)

##### Bug Fixes

- normalize full project collaborators
([#&#8203;652](https://redirect.github.com/Doist/todoist-sdk-typescript/issues/652))
([7712c5d](https://redirect.github.com/Doist/todoist-sdk-typescript/commit/7712c5dc7a558fa725f92604646ddbdac6cd23c2))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
|
[semantic-release](https://redirect.github.com/semantic-release/semantic-release)
| [`25.0.8` →
`25.0.9`](https://renovatebot.com/diffs/npm/semantic-release/25.0.8/25.0.9)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/semantic-release/25.0.9?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/semantic-release/25.0.8/25.0.9?slim=true)
|

---

### Release Notes

<details>
<summary>semantic-release/semantic-release (semantic-release)</summary>

###
[`v25.0.9`](https://redirect.github.com/semantic-release/semantic-release/releases/tag/v25.0.9)

[Compare
Source](https://redirect.github.com/semantic-release/semantic-release/compare/v25.0.8...v25.0.9)

##### Bug Fixes

- do not expose the authenticated repository URL in EGITNOPERMISSION
errors
([#&#8203;4283](https://redirect.github.com/semantic-release/semantic-release/issues/4283))
([8d905a5](https://redirect.github.com/semantic-release/semantic-release/commit/8d905a56e80030c141a71a32c0c4cb870e90470a))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oxfmt](https://oxc.rs/docs/guide/usage/formatter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt))
| [`0.61.0` →
`0.62.0`](https://renovatebot.com/diffs/npm/oxfmt/0.61.0/0.62.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxfmt/0.62.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxfmt/0.61.0/0.62.0?slim=true)
|
| [oxlint](https://oxc.rs/docs/guide/usage/linter)
([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint))
| [`1.76.0` →
`1.77.0`](https://renovatebot.com/diffs/npm/oxlint/1.76.0/1.77.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oxlint/1.77.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxlint/1.76.0/1.77.0?slim=true)
|

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxfmt)</summary>

###
[`v0.62.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxfmt/CHANGELOG.md#0620---2026-08-03)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.61.0...oxfmt_v0.62.0)

##### 🐛 Bug Fixes

-
[`e6e584b`](https://redirect.github.com/oxc-project/oxc/commit/e6e584b)
oxfmt: Type jsdoc. enum options
([#&#8203;25008](https://redirect.github.com/oxc-project/oxc/issues/25008))
(leaysgur)

</details>

<details>
<summary>oxc-project/oxc (oxlint)</summary>

###
[`v1.77.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#1770---2026-08-03)

[Compare
Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v1.76.0...oxlint_v1.77.0)

##### 🐛 Bug Fixes

-
[`5c0fa61`](https://redirect.github.com/oxc-project/oxc/commit/5c0fa61)
linter/eslint/no-warning-comments: Unify config structs and remove
manual options docs
([#&#8203;25151](https://redirect.github.com/oxc-project/oxc/issues/25151))
(Mikhail Baev)

##### 📚 Documentation

-
[`9dc7756`](https://redirect.github.com/oxc-project/oxc/commit/9dc7756)
linter/typescript/no-unnecessary-condition: Clarify options
([#&#8203;25110](https://redirect.github.com/oxc-project/oxc/issues/25110))
(camc314)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [marked](https://marked.js.org)
([source](https://redirect.github.com/markedjs/marked)) | [`18.0.7` →
`18.0.9`](https://renovatebot.com/diffs/npm/marked/18.0.7/18.0.9) |
![age](https://developer.mend.io/api/mc/badges/age/npm/marked/18.0.9?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/marked/18.0.7/18.0.9?slim=true)
|

---

### Release Notes

<details>
<summary>markedjs/marked (marked)</summary>

###
[`v18.0.9`](https://redirect.github.com/markedjs/marked/compare/v18.0.8...8e858a4f8e7f53ffeae7392a4c9f455e693aa737)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v18.0.8...v18.0.9)

###
[`v18.0.8`](https://redirect.github.com/markedjs/marked/releases/tag/v18.0.8)

[Compare
Source](https://redirect.github.com/markedjs/marked/compare/v18.0.7...v18.0.8)

##### Bug Fixes

- fall back to default checkbox renderer when extension returns false
([#&#8203;4023](https://redirect.github.com/markedjs/marked/issues/4023))
([e1b6139](https://redirect.github.com/markedjs/marked/commit/e1b6139fec38345460f0df901723d8cdbade4fbf))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary

- split saved comma-separated filters into API-supported section queries
- fetch sections concurrently and preserve section order in human, JSON,
and NDJSON output
- add regression coverage and update the agent command reference

Closes #274

## Why

Todoist saved filters use commas to display queries as separate lists.
However, the public [Get Tasks By Filter API
documentation](https://developer.todoist.com/api/v1/#tag/Tasks/operation/get_tasks_by_filter_api_v1_tasks_filter_get)
states: “Multiple filters (using the comma `,` operator) are not
supported.”

The CLI passed the full saved query to that endpoint, which returned a
successful empty result. This change splits the saved query and calls
the endpoint once per section.

## Behavior and deliberate simplifications

- Each non-empty section has an independent API request and cursor
stream.
- Sections run concurrently through a worker pool capped at six active
section streams. This limits request bursts while keeping common filters
fully parallel.
- Pages within one section remain sequential because each page needs the
previous cursor.
- Results preserve the saved section order even if responses complete
out of order.
- Parsing is deliberately limited to finding unescaped commas. It is not
a full Todoist query parser.
- A comma preceded by an odd number of backslashes is preserved as a
literal. Escapes remain in the subquery sent to the API.
- Quotes and parentheses do not protect unescaped commas. Todoist
documents an unescaped comma as the separate-list operator and backslash
as the escape mechanism.
- Empty fragments, such as the middle fragment in `today,,tomorrow`, are
ignored.
- Results are not deduplicated. The same task can intentionally appear
in more than one section.
- If any section request fails, the whole command fails instead of
returning output that looks complete.
- Empty multi-section results do not load unrelated project or
collaborator data.
- `--limit` applies independently to each section.
- `--cursor` is rejected for multi-section filters because one cursor
cannot represent several independent streams. Use `--all`, or query one
section directly. Structured output includes `nextCursor` per section.
- Multi-section JSON uses `{ sections: [{ query, results, nextCursor }]
}`. NDJSON emits one section object per line. Single-section output
stays unchanged.

## Validation

- Reproduced with an isolated saved filter containing three
comma-separated queries. Before the fix, the saved filter returned zero
tasks while each component query returned one task.
- Re-ran the same saved filter with the local build. Human, JSON, and
NDJSON output each returned three sections with one expected task per
section.
- Removed the temporary filter, project, and tasks after validation.

## Tests

- `npm run type-check`
- `npm run check`
- `npm run check:skill-sync`
- `npm test` — 1,795 tests pass

---------

Co-authored-by: Scott Lovegrove <scott@ferretlabs.com>
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [oauth4webapi](https://redirect.github.com/panva/oauth4webapi) |
[`3.8.6` →
`3.8.7`](https://renovatebot.com/diffs/npm/oauth4webapi/3.8.6/3.8.7) |
![age](https://developer.mend.io/api/mc/badges/age/npm/oauth4webapi/3.8.7?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oauth4webapi/3.8.6/3.8.7?slim=true)
|

---

### Release Notes

<details>
<summary>panva/oauth4webapi (oauth4webapi)</summary>

###
[`v3.8.7`](https://redirect.github.com/panva/oauth4webapi/blob/HEAD/CHANGELOG.md#387-2026-08-11)

[Compare
Source](https://redirect.github.com/panva/oauth4webapi/compare/v3.8.6...v3.8.7)

##### Fixes

- **types:** expose custom fetch duplex option
([0dcd746](https://redirect.github.com/panva/oauth4webapi/commit/0dcd746f3a9d7e927e5be845e16731170b69ba60))
- **types:** make CryptoKey declarations portable
([1c85396](https://redirect.github.com/panva/oauth4webapi/commit/1c85396ae9905160472d8f95803aa90440182953))
- **types:** make JWK declarations interoperable
([ff804a8](https://redirect.github.com/panva/oauth4webapi/commit/ff804a8fd2cd0dcd911a2dede4d65a1816deae9d))

##### Documentation

- improve API index tables
([2c4b025](https://redirect.github.com/panva/oauth4webapi/commit/2c4b025a5cd79097cca4f72b7c15b9b71b7dca07))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yOS41IiwidXBkYXRlZEluVmVyIjoiNDQuMjkuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…mits to v10.3.0 (#475)

This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
|
[conventional-changelog-conventionalcommits](https://conventional-changelog.js.org/presets/conventional-commits/)
([source](https://redirect.github.com/conventional-changelog/conventional-changelog/tree/HEAD/packages/conventional-changelog-conventionalcommits))
| [`10.2.1` →
`10.3.0`](https://renovatebot.com/diffs/npm/conventional-changelog-conventionalcommits/10.2.1/10.3.0)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/conventional-changelog-conventionalcommits/10.3.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/conventional-changelog-conventionalcommits/10.2.1/10.3.0?slim=true)
|

---

### Release Notes

<details>
<summary>conventional-changelog/conventional-changelog
(conventional-changelog-conventionalcommits)</summary>

###
[`v10.3.0`](https://redirect.github.com/conventional-changelog/conventional-changelog/blob/HEAD/packages/conventional-changelog-conventionalcommits/CHANGELOG.md#1030-2026-08-10)

[Compare
Source](https://redirect.github.com/conventional-changelog/conventional-changelog/compare/conventional-changelog-conventionalcommits-v10.2.1...conventional-changelog-conventionalcommits-v10.3.0)

##### Features

- format references in breaking change notes
([#&#8203;1529](https://redirect.github.com/conventional-changelog/conventional-changelog/issues/1529))
([a8ef1ed](https://redirect.github.com/conventional-changelog/conventional-changelog/commit/a8ef1eda4526785460daa1f85a415eee326f291c)),
closes
[#&#8203;631](https://redirect.github.com/conventional-changelog/conventional-changelog/issues/631)
- group notes by their keyword
([#&#8203;1533](https://redirect.github.com/conventional-changelog/conventional-changelog/issues/1533))
([7be33d4](https://redirect.github.com/conventional-changelog/conventional-changelog/commit/7be33d4bac4917340063e2186477f3a121541734)),
closes
[#&#8203;815](https://redirect.github.com/conventional-changelog/conventional-changelog/issues/815)

##### Bug Fixes

- use current host url paths
([#&#8203;1534](https://redirect.github.com/conventional-changelog/conventional-changelog/issues/1534))
([612d368](https://redirect.github.com/conventional-changelog/conventional-changelog/commit/612d36822d3f0bf4c3041e85d19175faf55da7cf)),
closes
[#&#8203;986](https://redirect.github.com/conventional-changelog/conventional-changelog/issues/986)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Monday through Friday (`* * * * 1-5`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/Doist/todoist-cli).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yOS41IiwidXBkYXRlZEluVmVyIjoiNDQuMjkuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
`td filter view` printed tasks in whatever order the API returned. Todoist
doesn't sort server-side: every client sorts locally, first by the sorting
saved on the view and then, when the view has none, by a documented default
hierarchy. The CLI read neither piece.

Adds `src/lib/task-sort.ts` for the ordering itself and
`src/lib/api/view-options.ts` to read the saved view options, then wires
both into `filter view` behind `--sort` and `--sort-order`. Each section of
a multi-query filter sorts on its own, and `--json` / `--ndjson` come back
in the same order as the pretty output.

The view options are read with a direct `/sync` POST rather than
`api.sync()`. The SDK schema types `object_id` as a required string, but
the API returns null for the Today and Upcoming rows, so a typed sync
throws for anyone who has customised either view.

Closes #473

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@doistbot

doistbot commented Aug 17, 2026

Copy link
Copy Markdown
Member

🚨 Skipping review: PR size is too large

👋 @craigcarlyle I'm skipping this review because the PR is too large for a coherent Doistbot review (or for that matter a human review ☠️)

Reviewable diff: 7,606 review-load lines across 129 files (+7606 / -2385), excluding low-signal files 😱

ℹ️ To make it easier for your colleagues to review, the recommended diff size is < 750 review-load lines and < 25 files changed

Please split this into smaller PRs or a PR stack 🥺🙏

🪄 Suggested slicing plan 👇

The PR targets base branch `next` (which is at v1.68.0) instead of `main`, causing the diff to incorporate 67 upstream commits spanning 15 releases (v1.73.4 through v3.1.9) across 129 files and nearly 10,000 lines. The actual intended contribution is only the filter task sorting feature (affecting 6 files: `src/lib/task-sort.ts`, `src/lib/api/view-options.ts`, `src/commands/filter/view.ts`, `src/commands/filter/index.ts`, and tests). Slicing 129 files against `next` would artificially reconstruct and re-review already-shipped historical releases rather than produce valid review units. Base branch divergence: The PR base branch `next` is outdated (at v1.68.0), dragging in 67 commits already merged into `main` and published up to v3.1.9. Upstream release contamination: 123 of the 129 files belong to prior releases, including breaking major releases (v2.0.0 removing goals, v3.0.0 requiring Node &gt;=24), SDK updates (v10 to v13), and cli-core upgrades. Coupling to current `main`: The filter sorting implementation relies on the updated `@doist/todoist-sdk` (v13.0.2) and the section query architecture from PR #472, making it impossible to isolate against `next` without the upstream commits from `main`. Remediation: Retargeting the pull request base branch to `main` (or fast-forwarding `next` to match `main`) isolates the actual filter sorting change to 6 files and ~1,200 review lines as a single coherent unit.

A human familiar with the change should identify an intermediate, buildable boundary before splitting this PR.

You can use your agent of choice (Codex/Claude etc) to help you split this PR 😊 Just copy the link to this comment and ask them Can you please create a PR stack based on the suggestions in this comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.