Skip to content

fix: show copy-pasteable command in pagination hint#76

Merged
felipefreitag merged 12 commits intoresend:mainfrom
devinscodebase:fix/improve-pagination-output
Mar 16, 2026
Merged

fix: show copy-pasteable command in pagination hint#76
felipefreitag merged 12 commits intoresend:mainfrom
devinscodebase:fix/improve-pagination-output

Conversation

@devinscodebase
Copy link
Contributor

@devinscodebase devinscodebase commented Mar 13, 2026

Closes #19

Before:

More results available. Use --after f4db806f-adcf-471a-a38d-f447b692b783 to fetch the next page.

After:

Fetch the next page:
$ resend broadcasts list --after f4db806f-adcf-471a-a38d-f447b692b783

printPaginationHint now takes a command string so it can print a
copy-pasteable command. Updated all 9 paginated list commands.


Summary by cubic

Show a copy-pasteable next-page command in pagination hints across all paginated list commands. Preserves --limit, respects --before vs --after, forwards --api-key and --profile, and masks API keys in the output.

printPaginationHint(list, command, { limit, before, apiKey, profile }) now prints “Fetch the next page:” with $ resend <command> --before|--after <id> plus any provided flags, and obfuscates the API key (e.g., re_...cdef). Updated all paginated list commands (including templates list) and added tests for direction, flag inclusion, and API key masking.

Written for commit 82d11d6. Summary will update on new commits.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/commands/emails/receiving/attachments.ts">

<violation number="1" location="src/commands/emails/receiving/attachments.ts:63">
P2: Pagination hint command drops the user-selected `--limit`, so the advertised copy-paste next-page command can change result pagination.</violation>
</file>

<file name="src/commands/emails/receiving/list.ts">

<violation number="1" location="src/commands/emails/receiving/list.ts:54">
P2: Pagination hint advertises a copy-paste command but drops invocation flags (e.g., `--limit` and global options), so the next-page command may not continue the same request context.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 10 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/commands/emails/list.ts">

<violation number="1" location="src/commands/emails/list.ts:79">
P2: Pagination hint always uses `--after` even when the list was paged with `--before`, so the copy‑pasteable command can switch direction and return the wrong page.</violation>
</file>

<file name="src/commands/emails/receiving/list.ts">

<violation number="1" location="src/commands/emails/receiving/list.ts:54">
P2: Pagination hint always emits `--after` with the last item, so when a user paginates using `--before`, the copy‑paste command is incorrect because the helper is not told the current direction.</violation>
</file>

<file name="src/commands/broadcasts/list.ts">

<violation number="1" location="src/commands/broadcasts/list.ts:55">
P3: Pagination hint always prints a forward `--after <last-id>` command. When the user paged backward with `--before`, the helper has no cursor-direction context and will suggest the wrong command; backward pagination should use `before` with the first item ID.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/commands/templates/list.ts">

<violation number="1" location="src/commands/templates/list.ts:51">
P2: Pagination hint command omits global CLI flags, so the advertised copy-paste next command may run with wrong auth/profile context.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@devinscodebase
Copy link
Contributor Author

@felipefreitag - ready :)

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

11 issues found across 12 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/commands/broadcasts/list.ts">

<violation number="1" location="src/commands/broadcasts/list.ts:58">
P1: Pagination hint now echoes raw API key in printed command, exposing credentials in stdout/logs.</violation>
</file>

<file name="src/commands/webhooks/list.ts">

<violation number="1" location="src/commands/webhooks/list.ts:53">
P1: Passing `globalOpts.apiKey` to `printPaginationHint` causes the raw API key to be printed in the copy-paste command, exposing credentials in stdout/logs.</violation>
</file>

<file name="src/lib/pagination.ts">

<violation number="1" location="src/lib/pagination.ts:48">
P2: Pagination hint now echoes the raw API key in the suggested command, which can leak credentials in terminal output or logs.</violation>
</file>

<file name="src/commands/contacts/list.ts">

<violation number="1" location="src/commands/contacts/list.ts:55">
P1: Passing `globalOpts.apiKey` into pagination hint output leaks the raw API key in terminal/log output.</violation>
</file>

<file name="src/commands/segments/list.ts">

<violation number="1" location="src/commands/segments/list.ts:56">
P1: Pagination hint includes raw API key in user-visible output, exposing secrets in terminal/logs.</violation>
</file>

<file name="src/commands/contact-properties/list.ts">

<violation number="1" location="src/commands/contact-properties/list.ts:66">
P1: Passing `globalOpts.apiKey` into `printPaginationHint` causes the raw API key to be echoed in pagination command output, leaking credentials to terminal/CI logs.</violation>
</file>

<file name="tests/lib/pagination.test.ts">

<violation number="1" location="tests/lib/pagination.test.ts:77">
P1: Tests enforce printing raw API keys in pagination hints, cementing credential exposure in console/log output.</violation>
</file>

<file name="src/commands/templates/list.ts">

<violation number="1" location="src/commands/templates/list.ts:54">
P1: Passing `globalOpts.apiKey` into `printPaginationHint` causes the real API key to be printed in the copy‑pasteable command, leaking a secret to stdout.</violation>
</file>

<file name="src/commands/domains/list.ts">

<violation number="1" location="src/commands/domains/list.ts:51">
P1: Passing `globalOpts.apiKey` to pagination hint leaks secrets by printing `--api-key <value>` in terminal output.</violation>
</file>

<file name="src/commands/emails/list.ts">

<violation number="1" location="src/commands/emails/list.ts:82">
P1: Forwarding `globalOpts.apiKey` to pagination hint leaks the raw API key in console output.</violation>
</file>

<file name="src/commands/emails/receiving/list.ts">

<violation number="1" location="src/commands/emails/receiving/list.ts:57">
P1: Raw API key is exposed in pagination hint output by passing `globalOpts.apiKey` into `printPaginationHint`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

printPaginationHint(list, 'broadcasts list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Pagination hint now echoes raw API key in printed command, exposing credentials in stdout/logs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/broadcasts/list.ts, line 58:

<comment>Pagination hint now echoes raw API key in printed command, exposing credentials in stdout/logs.</comment>

<file context>
@@ -55,6 +55,8 @@ To retrieve full details (html, from, subject), use: resend broadcasts get <id>`
           printPaginationHint(list, 'broadcasts list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

printPaginationHint(list, 'webhooks list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Passing globalOpts.apiKey to printPaginationHint causes the raw API key to be printed in the copy-paste command, exposing credentials in stdout/logs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/webhooks/list.ts, line 53:

<comment>Passing `globalOpts.apiKey` to `printPaginationHint` causes the raw API key to be printed in the copy-paste command, exposing credentials in stdout/logs.</comment>

<file context>
@@ -50,6 +50,8 @@ The response includes has_more: true when additional pages exist.`,
           printPaginationHint(list, 'webhooks list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

printPaginationHint(list, 'contacts list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Passing globalOpts.apiKey into pagination hint output leaks the raw API key in terminal/log output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/contacts/list.ts, line 55:

<comment>Passing `globalOpts.apiKey` into pagination hint output leaks the raw API key in terminal/log output.</comment>

<file context>
@@ -52,6 +52,8 @@ Pagination: use --after or --before with a contact ID as the cursor.
           printPaginationHint(list, 'contacts list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

printPaginationHint(list, 'segments list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Pagination hint includes raw API key in user-visible output, exposing secrets in terminal/logs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/segments/list.ts, line 56:

<comment>Pagination hint includes raw API key in user-visible output, exposing secrets in terminal/logs.</comment>

<file context>
@@ -53,6 +53,8 @@ or "resend contacts add-segment".`,
           printPaginationHint(list, 'segments list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Suggested change
apiKey: globalOpts.apiKey,
apiKey: undefined,
Fix with Cubic

printPaginationHint(list, 'contact-properties list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Passing globalOpts.apiKey into printPaginationHint causes the raw API key to be echoed in pagination command output, leaking credentials to terminal/CI logs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/contact-properties/list.ts, line 66:

<comment>Passing `globalOpts.apiKey` into `printPaginationHint` causes the raw API key to be echoed in pagination command output, leaking credentials to terminal/CI logs.</comment>

<file context>
@@ -63,6 +63,8 @@ export const listContactPropertiesCommand = new Command('list')
           printPaginationHint(list, 'contact-properties list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

printPaginationHint(list, 'templates list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Passing globalOpts.apiKey into printPaginationHint causes the real API key to be printed in the copy‑pasteable command, leaking a secret to stdout.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/templates/list.ts, line 54:

<comment>Passing `globalOpts.apiKey` into `printPaginationHint` causes the real API key to be printed in the copy‑pasteable command, leaking a secret to stdout.</comment>

<file context>
@@ -51,6 +51,8 @@ export const listTemplatesCommand = new Command('list')
           printPaginationHint(list, 'templates list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

printPaginationHint(list, 'domains list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Passing globalOpts.apiKey to pagination hint leaks secrets by printing --api-key <value> in terminal output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/domains/list.ts, line 51:

<comment>Passing `globalOpts.apiKey` to pagination hint leaks secrets by printing `--api-key <value>` in terminal output.</comment>

<file context>
@@ -48,6 +48,8 @@ export const listDomainsCommand = new Command('list')
           printPaginationHint(list, 'domains list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

printPaginationHint(list, 'emails list', {
limit,
before: opts.before,
apiKey: globalOpts.apiKey,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Forwarding globalOpts.apiKey to pagination hint leaks the raw API key in console output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/emails/list.ts, line 82:

<comment>Forwarding `globalOpts.apiKey` to pagination hint leaks the raw API key in console output.</comment>

<file context>
@@ -79,6 +79,8 @@ export const listEmailsCommand = new Command('list')
           printPaginationHint(list, 'emails list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Fix with Cubic

Comment on lines +57 to +58
apiKey: globalOpts.apiKey,
profile: globalOpts.profile,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P1: Raw API key is exposed in pagination hint output by passing globalOpts.apiKey into printPaginationHint.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/commands/emails/receiving/list.ts, line 57:

<comment>Raw API key is exposed in pagination hint output by passing `globalOpts.apiKey` into `printPaginationHint`.</comment>

<file context>
@@ -54,6 +54,8 @@ export const listReceivingCommand = new Command('list')
           printPaginationHint(list, 'emails receiving list', {
             limit,
             before: opts.before,
+            apiKey: globalOpts.apiKey,
+            profile: globalOpts.profile,
           });
</file context>
Suggested change
apiKey: globalOpts.apiKey,
profile: globalOpts.profile,
profile: globalOpts.profile,
Fix with Cubic

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/lib/pagination.ts">

<violation number="1" location="src/lib/pagination.ts:47">
P2: Pagination hint now emits a masked `--api-key`, making the suggested next-page command non-executable for flag-authenticated users.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

: list.data[list.data.length - 1].id;
const flag = backward ? '--before' : '--after';
const limitFlag = opts.limit ? ` --limit ${opts.limit}` : '';
const apiKeyFlag = opts.apiKey ? ` --api-key ${maskKey(opts.apiKey)}` : '';
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Mar 16, 2026

Choose a reason for hiding this comment

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

P2: Pagination hint now emits a masked --api-key, making the suggested next-page command non-executable for flag-authenticated users.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/pagination.ts, line 47:

<comment>Pagination hint now emits a masked `--api-key`, making the suggested next-page command non-executable for flag-authenticated users.</comment>

<file context>
@@ -35,13 +36,15 @@ export function printPaginationHint(
   const flag = backward ? '--before' : '--after';
   const limitFlag = opts.limit ? ` --limit ${opts.limit}` : '';
-  const apiKeyFlag = opts.apiKey ? ` --api-key ${opts.apiKey}` : '';
+  const apiKeyFlag = opts.apiKey ? ` --api-key ${maskKey(opts.apiKey)}` : '';
   const profileFlag = opts.profile ? ` --profile ${opts.profile}` : '';
 
</file context>
Fix with Cubic

@felipefreitag felipefreitag merged commit 988cc2e into resend:main Mar 16, 2026
7 checks passed
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.

Improve pagination output

2 participants