Skip to content

feat: Add Todoist OAuth for Comms auth#15

Merged
amix merged 8 commits into
mainfrom
amix/comms-todoist-oauth
Jun 5, 2026
Merged

feat: Add Todoist OAuth for Comms auth#15
amix merged 8 commits into
mainfrom
amix/comms-todoist-oauth

Conversation

@amix

@amix amix commented Jun 4, 2026

Copy link
Copy Markdown
Member

Context

Adds Todoist OAuth as the Comms CLI auth flow.

What was changed

  • Register public Todoist OAuth clients with PKCE and Comms resource support
  • Request Comms scopes, with explicit --full-access for delete/admin scopes
  • Persist OAuth client/resource metadata and refresh token metadata safely
  • Refresh OAuth access tokens and keep API/search clients resource-aware
  • Reset stale workspace selection after OAuth relogin

Testing

  • npm run check:skill-sync
  • npm run type-check
  • npm test
  • npm run lint:check
  • doistbot review staged (one local pass, concrete findings addressed)

Add Todoist OAuth as the CLI auth flow for Comms, including Comms scopes, public DCR client registration, PKCE token exchange, refresh handling, persisted OAuth metadata, and resource-aware Comms API/search clients.
@amix amix requested a review from doistbot June 4, 2026 18:50
@doistbot doistbot requested a review from pedroalves0 June 4, 2026 18:50
@amix amix requested a review from scottlovegrove June 4, 2026 18:52

@doistbot doistbot left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work Amir on integrating the Todoist OAuth flow into the Comms CLI 😊.

Few things worth tightening:

  • The local storage of delegated OAuth tokens conflicts with the internal AI tools standard; this flow needs to be moved behind an approved server-side service.
  • The tdc doctor and tdc auth status commands currently bypass token refresh or stored resources, causing valid staging/local sessions to appear broken.
  • Type the provider handshake explicitly instead of using a generic record, and ensure the refresh logic requires the complete set of OAuth metadata to avoid silent fallbacks.
  • Add test coverage for the getCommsClient() resource wiring and the refresh fallback scenario where the token response omits the scope.

I also included a few optional follow-up notes in the details below.

Optional follow-up notes (2)
  • [P3] src/commands/auth/login.ts:24: getConfig() and store.active(account.id) are independent I/O, but this path waits for them serially. On keyring-backed setups that adds avoidable latency to every successful OAuth login. Fetching them in parallel (for example with separate promises or Promise.allSettled) would keep the new workspace-reset step from stretching login time.
  • [P3] src/commands/auth/login.ts:44: This always does workspaces.getWorkspaces() once login succeeds, even when there is no stored currentWorkspace. That adds a full extra API round-trip to fresh OAuth logins just to prefill workspace state, while getCurrentWorkspaceId() already resolves and persists a workspace lazily on first real use. If the main goal is clearing stale selections, consider skipping this lookup when currentWorkspace is unset.

Share FeedbackReview Logs

Comment thread src/lib/auth.ts Outdated
Comment thread src/lib/api.ts
Comment thread src/lib/auth.ts
Comment thread src/lib/auth-provider.ts
Comment thread src/lib/api.test.ts
Comment thread src/lib/auth-provider.test.ts Outdated
Comment thread src/lib/auth.ts
amix added 2 commits June 4, 2026 21:00
Keep the OAuth test suite focused on DCR, token exchange, refresh, Comms resource handling, workspace reset behavior, and diagnostics.
Use refreshed account snapshots and stored Comms resources when auth status and doctor validate OAuth tokens.
@amix

amix commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

Posted by Claude Code/Codex on behalf of Amir:

Addressed the concrete PR-level points in follow-up commits:

  • tdc auth status now refreshes through getApiTokenSnapshot(account.id) and validates against the stored authResource.
  • tdc doctor now validates against the probed authResource.
  • Refresh requires the OAuth client metadata before attempting a refresh; legacy OAuth tokens are only used until actual expiry.
  • Trimmed redundant OAuth tests so the remaining coverage focuses on DCR, token exchange, refresh, Comms resource handling, workspace reset, and diagnostics.

The server-side token-storage point is out of scope for this CLI PR. This PR keeps local OS credential storage plus config fallback, matching the existing CLI auth model.

Not requesting another Doistbot round per Amir's direction.

amix and others added 4 commits June 4, 2026 21:58
Refresh doctor probes online, fail closed on partial OAuth metadata, and cover resource-aware shared client creation.
…lled OAuth

Bump @doist/cli-core to 0.25.0 and replace comms-cli's bespoke DCR
registration / PKCE authorize / token exchange / refresh implementation with a
composition of cli-core's createDcrProvider, now that it supports the three
things comms-cli needed: the RFC 8707 resource indicator, refresh-token
support, and loadClient/saveClient client caching.

auth-provider.ts shrinks ~507 lines net. What stays Comms-specific:
- endpoint + resource resolution from COMMS_BASE_URL / COMMS_AS_URL,
- the config client cache wired through loadClient/saveClient (keyed on
  redirectUri),
- recording the server-granted scope (an exchangeCode wrapper stashes it on the
  handshake for validate; refreshToken rebuilds the account from it) — using the
  scope cli-core now surfaces on ExchangeResult,
- the token-response diagnostics surfaced when Comms rejects a token,
- validate: getSessionUser probe + authMode derivation,
- the COMMS_API_TOKEN token-store override.

The refresh handshake is reconstructed from the stored account (clientId +
resource/authBaseUrl + identity fields) since cli-core doesn't persist it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread src/commands/auth/login.ts Outdated
Comment thread src/commands/auth/status.ts Outdated
Comment thread src/commands/auth/status.ts
Comment thread src/commands/view.test.ts
Comment thread src/commands/view.ts
Comment thread src/lib/auth-provider.ts Outdated
Comment thread src/lib/auth-provider.ts Outdated
@amix amix requested a review from scottlovegrove June 5, 2026 16:03
@amix

amix commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@scottlovegrove I’ll merge this in, I think I resolved all of the issues. if something is off, let me know and I’ll do a follow-up.

@amix amix merged commit cd64fa7 into main Jun 5, 2026
5 checks passed
@amix amix deleted the amix/comms-todoist-oauth branch June 5, 2026 16:04
doist-release-bot Bot added a commit that referenced this pull request Jun 5, 2026
## [1.5.0](v1.4.0...v1.5.0) (2026-06-05)

### Features

* Add Todoist OAuth for Comms auth ([#15](#15)) ([cd64fa7](cd64fa7))
@doist-release-bot

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.5.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants