feat: adopt cli-core DCR provider + account command attachers#5
Conversation
Replace the bespoke DCR AuthProvider (hand-rolled registration, PKCE authorize, HTTP Basic token exchange) with cli-core's createDcrProvider, driven by oauth4webapi. The only comms-specific piece left is validate, which probes getSessionUser and derives authMode/authScope from the folded handshake.readOnly via a shared getScopes() helper. Use client_secret_post (not the default client_secret_basic): client_ids can contain underscores, which the basic form url-encodes (_ -> %5F) and the token endpoint doesn't decode, breaking the lookup. Bump @doist/cli-core 0.16.1 -> 0.24.0 and add oauth4webapi as a direct dependency. The 0.24.0 TokenStore contract change (clear() -> ClearedAccount | null, required activeAccount/setBundle/activeBundle) is threaded through the store override and test mocks. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the hand-rolled account list/use/remove/current commands with
cli-core's attachAccount*Command, deleting list.ts/use.ts/remove.ts/
current.ts. The attachers own the command action and JSON envelopes
({accounts,default} for list, {ok,default} for use, {ok,removed} for
remove), so comms-specific behaviour moves into their hooks:
- current: env-token resolves as null from activeAccount() and renders
the env notice via onNotAuthenticated; an identity-less manual-token
account (empty id/label, persisted by `tdc auth token`) stays a
resolved account and is special-cased in renderText/renderJson as
source: token-only.
- list: wrapped so manual-token snapshots stay out of the roster.
- remove: onRemoved surfaces the keyring-fallback warning on stderr.
Add an activeAccount() override to the store (env -> null) mirroring
active()/activeBundle(), and forward clear()'s ClearedAccount return
through withUserRefAware.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Descriptive ~2000-token orientation file (matching the cli-core / todoist-cli style) so agents and humans can navigate the repo without exploring. Covers the lazy command registry, command/lib catalogs, ref resolution, the env-token + manual-token auth path, testing, and the skill-content flow. Complements AGENTS.md (prescriptive rules). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
doistbot
left a comment
There was a problem hiding this comment.
This PR successfully ports the cli-core DCR provider and account command attachers, standardizing the multi-account workflows while removing bespoke boilerplate. Adopting upstream JSON envelopes and shared attachers significantly improves maintainability and aligns the project with other Doist CLI tools. A few areas could use minor refinement, including addressing edge cases with --ndjson output and hidden manual-token targeting, extracting duplicated logout result logic, utilizing public Commander APIs for default commands, and expanding test coverage for the new account store logic.
Address review feedback on the account-attacher refactor: - matchCommsAccount() now never matches an identity-less manual-token account, so an empty-ish ref (`""`, `id:`) passed to `account use` / `remove` can't target a row that `list` deliberately hides. - Extract the shared `logStoredTokenRemoval` helper (auth/helpers.ts) so `auth logout`'s onCleared and `account remove`'s onRemoved can't drift. - Add tests: manual-token rows hidden from `account list` (human + json), the matchCommsAccount manual-token guard, and the store's activeAccount() env-token short-circuit + delegation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## 1.0.0 (2026-05-25) ### Features * add channel create and update commands ([#4](#4)) ([f097378](f097378)) * adopt cli-core DCR provider + account command attachers ([#5](#5)) ([4749a07](4749a07)) * bootstrap Comms CLI from twist-cli ([ea28735](ea28735)) * upgrade to @doist/comms-sdk@0.2.0 ([#2](#2)) ([ae4d6e1](ae4d6e1))
|
🎉 This PR is included in version 1.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
amix
left a comment
There was a problem hiding this comment.
Would have been great to seperate these in two distinct PRs.
I also think we should remove CODEBASE.md; this can quickly become stale 👍
It hasn't on any of the repos I've added it into because when new things get added, or stuff gets removed, the codebase.md gets updated by the agent, and the agent is actually who the file is for in the first place. |
|
✅ |
Summary
Ports two cli-core adoption changes from twist-cli (weekend of 2026-05-22) into comms-cli, bundled into one PR. Bumps
@doist/cli-core0.16.1 → 0.24.0and addsoauth4webapias a direct dependency.Upstream PRs ported here:
feat(auth): adopt cli-corecreateDcrProviderrefactor(account): adopt cli-core account command attachers (incl. its CODEBASE.md)feat(auth): adopt cli-corecreateDcrProvider(twist-cli#243)AuthProvider(hand-rolled registration, PKCE authorize, HTTP Basic token exchange) with cli-core'screateDcrProvider, driven byoauth4webapi. The only comms-specific piece left isvalidate, which probesgetSessionUserand derivesauthMode/authScopefrom the foldedhandshake.readOnlyvia a sharedgetScopes().client_secret_post(not the defaultclient_secret_basic): client_ids can contain_, which the basic form url-encodes (_→%5F) and the token endpoint doesn't decode.TokenStorecontract through the store override + test mocks (clear() → ClearedAccount | null, requiredactiveAccount/setBundle/activeBundle).refactor(account): adopt cli-core account attachers (twist-cli#250)list/use/remove/currentwithattachAccount*Command; delete those four files. Adopt cli-core's JSON envelopes ({accounts,default},{ok,default},{ok,removed}).withLegacyGuard/assertV2Availableis dropped. comms' manual-token model is adapted into the attacher hooks:currentreportssource: token-only,listhides identity-less rows.activeAccount()store override (env → null) mirroringactive()/activeBundle(); forwardclear()'sClearedAccountthroughwithUserRefAware.docs: add CODEBASE.md (part of twist-cli#250)Test plan
npm run type-checknpm run lint:check(oxlint + oxfmt) — 0 warnings/errorsnpm test— 630 tests pass (37 files)🤖 Generated with Claude Code