Skip to content

feat(account): account command group (cli-core attachers)#79

Merged
scottlovegrove merged 4 commits into
mainfrom
scottl/cli-core-account
May 24, 2026
Merged

feat(account): account command group (cli-core attachers)#79
scottlovegrove merged 4 commits into
mainfrom
scottl/cli-core-account

Conversation

@scottlovegrove
Copy link
Copy Markdown
Contributor

@scottlovegrove scottlovegrove commented May 24, 2026

Summary

Surfaces the multi-account storage (already shipped in #77users[] config, keyring, --user selector, withUserRefAware store-wrap) to users via a new ol account command group, wiring cli-core's four generic account attachers.

  • ol account list (and bare ol account, via default subcommand) — lists stored accounts with an accessibility-aware default marker; --json emits a { accounts, default } envelope, --ndjson streams one per line.
  • ol account use <id|name> — sets the default account used when --user is omitted.
  • ol account current — shows the active account, honours ol --user <ref>, and reports the OUTLINE_API_TOKEN env source and legacy single-user sessions via onNotAuthenticated (rather than rendering them as a blank stored account).
  • ol account remove <id|name> — clears the keyring + config entry and surfaces any keyring-fallback warning.
  • Machine output drops the OAuth client id ({ id, label, teamName, baseUrl, isDefault }).

Reuses existing plumbing: createOutlineTokenStore, withUserRefAware, matchOutlineAccount, logTokenStorageResult. No changes to the env/legacy resolution logic beyond a read-only wrapper for current.

Test plan

  • npm run type-check
  • npm run test — 200/200 pass, incl. new src/commands/account.test.ts (list/use/current/remove, env-token, legacy, empty, not-authenticated)
  • npm run format:check clean
  • npm run check:skill-sync in sync
  • node dist/index.js account --help renders all four subcommands + examples
  • Manual smoke against a real multi-account config: ol account, ol account use, ol --user <ref> account current, OUTLINE_API_TOKEN=… ol account current

🤖 Generated with Claude Code

Wire cli-core's account attachers into a new `ol account` group: list /
use / current / remove. The multi-account storage (users[] config +
keyring) and the `--user` selector / store-wrap shipped in #77; this
surfaces it to users.

- `ol account` defaults to `list`; default account marked (accessible-aware)
- `ol account current` honours `--user` and reports OUTLINE_API_TOKEN /
  legacy single-user sources via onNotAuthenticated
- machine output drops the OAuth client id
- SKILL_CONTENT gains an Accounts section (SKILL.md regenerated)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@doistbot doistbot left a comment

Choose a reason for hiding this comment

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

This PR successfully introduces the ol account command group, cleanly wrapping the underlying multi-account storage capabilities and providing a solid foundation for the next phase of the cli-core migration. The implementation effectively leverages our existing storage plumbing to make multi-user workflows significantly more intuitive. There are a few implementation details to refine, primarily around standardizing the JSON output shapes for machine consumers alongside their SKILL_CONTENT documentation, correcting the authentication fallback precedence, and avoiding duplicate configuration reads. Additionally, extracting some duplicated logic, utilizing Commander's native default routing, and simplifying the test mocks while expanding coverage for keyring fallbacks and --user overrides will help ensure the new commands are fully robust.

Share FeedbackReview Logs

Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/lib/skills/content.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.test.ts Outdated
Comment thread src/commands/account.test.ts
Comment thread src/commands/account.test.ts
- Fix auth precedence: prefer a stored v2 account over a lingering legacy
  token. `current` now only reports the legacy source when no v2 record
  backs the resolved account (was short-circuiting on any legacy session).
- Single discriminated `--json` envelope for `current`:
  {source:"stored", account} | {source:"env"} | {source:"legacy"};
  SKILL_CONTENT updated + SKILL.md regenerated.
- Resolve the ambient source once in the store wrapper and stash it, so the
  miss path no longer re-reads config via a second isLegacyAuthActive probe.
- Dedup the clear-result handling into a shared `logClearResult` in auth.ts,
  reused by `auth logout` and `account remove`.
- Drop redundant `?? account.id` (label is a required string).
- Tests: add --user override + keyring-fallback-warning coverage; legacy
  case no longer depends on isLegacyAuthActive.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottlovegrove
Copy link
Copy Markdown
Contributor Author

@doistbot /review

Copy link
Copy Markdown
Member

@doistbot doistbot left a comment

Choose a reason for hiding this comment

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

This PR successfully introduces the ol account command group to expose multi-account management capabilities to users. While the new commands effectively leverage existing attachers to enhance the CLI experience, there are a few opportunities to streamline the internal integration and test suite. Specifically, adjustments are needed to centralize the auth-source resolution logic to prevent duplication and redundant store reads, improve the accuracy of legacy account detection, and extract shared utilities out of sibling command modules. Further refinements to replace private Commander API usage and strengthen the tests with simpler stubs and comprehensive JSON coverage will help solidify the implementation.

Share FeedbackReview Logs

Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/auth.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.ts Outdated
Comment thread src/commands/account.test.ts Outdated
Comment thread src/commands/account.test.ts Outdated
Comment thread src/commands/account.test.ts Outdated
scottlovegrove and others added 2 commits May 24, 2026 15:47
- Add `resolveActiveAccountSource` to auth-provider as the authoritative
  env/stored/legacy classifier. It resolves the v2 account by ref via the
  bare keyring store, so a renamed legacy snapshot sharing a UUID with a v2
  record can no longer be misreported as `stored` (fixes the UUID-equality
  P1). `account current` now consumes it instead of re-deriving the cascade
  from a `store.list()` membership check — one store read on the normal path.
- Drop the `_defaultCommandName` private-field cast: bare `ol account` now
  delegates to `list` via a parent `.action()` (public commander API).
- Move `logTokenStorageResult` / `logClearResult` into `src/lib/auth-output.ts`
  so `account.ts` no longer imports a sibling command module.
- Tests: per-test stubs with explicit arg assertions; `current` stubs
  `resolveActiveAccountSource`; added --json/--ndjson coverage for the env
  and legacy source branches and a bad-`--user` ACCOUNT_NOT_FOUND case. The
  stored-vs-legacy precedence (incl. the renamed-legacy regression) is now
  covered directly in auth-provider.test.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`current` was wrapping the store in an `activeAccount` adapter + closure-stashed
source just to feed cli-core's generic account attacher, which only models
stored accounts. Resolve the source directly in the command action instead —
same behaviour and discriminated `--json` envelope, ~26 fewer lines, and no
store-wrapping indirection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scottlovegrove scottlovegrove merged commit 01bd6a6 into main May 24, 2026
5 checks passed
@scottlovegrove scottlovegrove deleted the scottl/cli-core-account branch May 24, 2026 15:02
doist-release-bot Bot added a commit that referenced this pull request May 24, 2026
## [1.9.0](v1.8.0...v1.9.0) (2026-05-24)

### Features

* **account:** account command group (cli-core attachers) ([#79](#79)) ([01bd6a6](01bd6a6)), closes [#77](#77)
@doist-release-bot
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.9.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.

2 participants