Conversation
|
Stack: wyattjoh/users-list
Part of a stacked PR chain. Do not merge manually. |
🦋 Changeset detectedLatest commit: 35d2af5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
clerk users list subcommand
bd40ab6 to
100ee59
Compare
List users from the target instance with pagination, query search, repeatable identifier filters, and order-by support. Human mode prints a compact table; agent mode and `--json` return the raw BAPI response.
Mirror `users create`: when invoked without a linked project, env var, or targeting flag, pop the shared application picker in human mode. Inside the menu's intro/outro block, route table rows to stderr so the gutter prefix is applied consistently.
…ields Drop web3wallet, updated_at, and last_active_at from the --order-by choice list. Keeps the five identifier fields rendered in the users list table plus created_at and last_sign_in_at, the two timestamps users actually sort by even though they aren't displayed.
The list, search-by-email, and `jq`-pipe scripting examples in the bundled clerk skill's `recipes.md` defaulted to raw `clerk api /users[?...]` calls. With `clerk users list` available, switch them to the curated command (with `--json` for the pipe forms) so agents reach for the dedicated subcommand by default. Count, fetch, update, and lifecycle recipes stay on raw API since their curated subcommands are still upstack.
Both the `users` parent command and its `list` subcommand define `--secret-key` / `--app` / `--instance`. When a subcommand redefines an option already set on its parent, commander attributes the parsed value to the parent's option object, so a child's bare `cmd.opts()` returns empty for those keys. The list action handler relied on commander's default invocation (which passes only local opts), so `clerk users list --app <id>` and `clerk users --app <id>` (interactive menu) silently dropped the targeting flags and fell through to the no-secret-key error, even though the documented usage in `users/README.md` includes both. Mirror the create subcommand's wiring: replace the bare `.action(handler)` with `.action((_opts, cmd) => handler(cmd.optsWithGlobals()))` for both the `users` parent menu action and the `users list` action. `create` already uses this pattern and works correctly. Adds an integration test covering the regression: `clerk users list --app app_1 --instance development` resolves the secret key via the Platform API without a linked project, then issues the BAPI list call.
60021bc to
13bc1e2
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a new Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/cli-core/src/commands/users/list.ts`:
- Around line 155-157: The current catch branch treats any
ERROR_CODE.NO_SECRET_KEY as OK to call resolveUsersInstanceContext (involving
resolveUsersInstanceContext and returning ctx.secretKey), which causes explicit
invocations with --app/--instance to fall into interactive picker; change the
condition around isHuman() && error instanceof CliError && error.code ===
ERROR_CODE.NO_SECRET_KEY to only perform the interactive fallback when the user
did NOT explicitly target an instance/app (i.e., ensure
options.instance/options.app are falsy), and otherwise rethrow or propagate the
CliError so targeted runs do not trigger resolveUsersInstanceContext; update the
logic surrounding resolveUsersInstanceContext and the error handling to reflect
this intent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 865fcf59-6d62-40a4-8b4a-d5b514d2e355
📒 Files selected for processing (10)
.changeset/users-list.mdpackages/cli-core/src/cli-program.test.tspackages/cli-core/src/cli-program.tspackages/cli-core/src/commands/users/README.mdpackages/cli-core/src/commands/users/index.tspackages/cli-core/src/commands/users/list.test.tspackages/cli-core/src/commands/users/list.tspackages/cli-core/src/lib/log.tspackages/cli-core/src/test/integration/users-commands.test.tsskills/clerk/references/recipes.md
`clerk users list` would silently switch applications if a user passed `--app <id>` (or other explicit targeting) and the resolved instance had no secret key — `resolveBapiSecretKey` threw NO_SECRET_KEY, and the catch opened the picker without preserving the explicit target. Surface the original error in those cases; only fall back to the picker when no target was provided.
Summary
Adds
clerk users list, the read side of theclerk usersfamily. Lists users from the target instance with first-class flags for the filters Clerk's Backend API exposes onGET /v1/users:--limit,--offset,--query, repeatable (or comma-separated)--email-address/--phone-number/--username/--user-id/--external-id, and--order-byover Clerk's common user ordering fields with optional+/-prefix. Anything beyond that stays out of scope and remains accessible viaclerk api.In human mode the command renders a concise table (name, user ID, primary identifier) and a row count footer.
--jsonand agent mode emit the full Backend API response body to stdout for piping. The network read is wrapped in the standardFetching users...spinner.The list action is also registered against the
clerk usersaction registry so it appears in the top-level interactive menu alongsidecreate. When invoked without a linked project, env var, or targeting flag in human mode, list now mirrorsusers createand pops the shared application picker so an unlinked user can choose an instance interactively. Direct invocation paths (--secret-key,CLERK_SECRET_KEY,--app, linked project) keep their original fast resolution. Agent mode preserves the originalNO_SECRET_KEYusage error.When the table is rendered inside the menu's intro/outro block, rows route to stderr so the gutter prefix (
│) is applied consistently with the surrounding UI. Direct invocation continues to print the table to stdout for piping.Test plan
bun run format:checkbun run lintbun run typecheckbun run testbun run test:e2e:opclerk users list --helpand confirm the filter / pagination / sort flags behave as documentedclerk usersmenu with no project linked, confirm List → picker → instance selection → table inside the gutter