Skip to content

fix(project-list): add pagination and flexible target parsing#221

Open
BYK wants to merge 25 commits intomainfrom
fix/project-list-pagination
Open

fix(project-list): add pagination and flexible target parsing#221
BYK wants to merge 25 commits intomainfrom
fix/project-list-pagination

Conversation

@BYK
Copy link
Member

@BYK BYK commented Feb 10, 2026

Summary

Fixes three bugs in sentry project list:

  • No pagination — showed "displaying 30 out of 100 projects" with no way to see the rest. Added --cursor/-c flag with a last magic value that resumes from where you left off.
  • API pagination not followed — setting -n 200 still capped at 100 because the Sentry API paginates and we never followed cursor links. Added orgScopedPaginateAll() so listProjects() transparently fetches all pages.
  • project list sentry/sentry said "No projects found in organization 'sentry/sentry'" — now uses parseOrgProjectArg() (same as issue list) to handle org/project, org/, and bare-word targets.

Changes

src/lib/api-client.ts — Pagination infrastructure

  • PaginatedResponse<T> type, parseLinkHeader(), orgScopedRequestPaginated(), orgScopedPaginateAll()
  • listProjects() now auto-paginates transparently (all 6 callers unchanged)
  • New listProjectsPaginated() for explicit single-page fetches with cursor control

src/commands/project/list.ts — Rewritten command

  • 4 target modes: auto-detect, explicit (org/project), org-all (org/), project-search (bare slug)
  • --cursor/-c flag with last magic value for easy page navigation
  • JSON output returns { data, nextCursor?, hasMore } in paginated mode

src/lib/db/schema.ts — Schema v6

  • Added pagination_cursors table for cursor caching

src/lib/db/pagination.ts — New module

  • Cursor cache with TTL (default 5 min) and context validation

Tests

  • Updated test/e2e/project.test.ts and test/e2e/multiregion.test.ts for new org/ syntax and paginated JSON format

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Build

  • Add hole-punch tool to reduce compressed binary size by BYK in #245
  • Add gzip-compressed binary downloads by BYK in #244

Bug Fixes 🐛

  • (project-list) Add pagination and flexible target parsing by BYK in #221
  • (upgrade) Remove v prefix from release URLs and work around Bun.write streaming bug by BYK in #243

Internal Changes 🔧

  • (build) Replace local hole-punch script with binpunch package by BYK in #246
  • Use @sentry/api client for requests by MathurAditya724 in #226

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 10, 2026

Codecov Results 📊

✅ Patch coverage is 86.39%. Project has 3965 uncovered lines.
✅ Project coverage is 70.32%. Comparing base (base) to head (head).

Files with missing lines (71)
File Patch % Lines
human.ts 58.29% ⚠️ 395 Missing
list.ts 14.39% ⚠️ 345 Missing
resolve-target.ts 25.17% ⚠️ 327 Missing
api-client.ts 66.62% ⚠️ 250 Missing
list.ts 23.47% ⚠️ 212 Missing
oauth.ts 30.68% ⚠️ 183 Missing
plan.ts 19.37% ⚠️ 154 Missing
resolver.ts 3.23% ⚠️ 120 Missing
help.ts 19.85% ⚠️ 109 Missing
upgrade.ts 61.37% ⚠️ 107 Missing
view.ts 36.48% ⚠️ 101 Missing
interactive-login.ts 9.17% ⚠️ 99 Missing
errors.ts 5.94% ⚠️ 95 Missing
view.ts 25.81% ⚠️ 92 Missing
view.ts 39.44% ⚠️ 86 Missing
clipboard.ts 4.49% ⚠️ 85 Missing
status.ts 24.07% ⚠️ 82 Missing
migration.ts 47.44% ⚠️ 82 Missing
list.ts 27.18% ⚠️ 75 Missing
browser.ts 4.11% ⚠️ 70 Missing
login.ts 33.33% ⚠️ 64 Missing
list.ts 85.71% ⚠️ 64 Missing
span-tree.ts 5.00% ⚠️ 57 Missing
explain.ts 33.33% ⚠️ 56 Missing
api.ts 89.80% ⚠️ 47 Missing
upgrade.ts 66.91% ⚠️ 46 Missing
telemetry.ts 84.72% ⚠️ 46 Missing
seer.ts 75.54% ⚠️ 45 Missing
refresh.ts 40.63% ⚠️ 38 Missing
schema.ts 90.57% ⚠️ 38 Missing
seer.ts 79.87% ⚠️ 30 Missing
preload.ts 53.23% ⚠️ 29 Missing
view.ts 87.27% ⚠️ 28 Missing
utils.ts 88.94% ⚠️ 25 Missing
view.ts 61.54% ⚠️ 25 Missing
detector.ts 90.10% ⚠️ 20 Missing
binary.ts 88.67% ⚠️ 17 Missing
list.ts 91.16% ⚠️ 16 Missing
list.ts 90.70% ⚠️ 16 Missing
help.ts 57.14% ⚠️ 15 Missing
sentry-client.ts 92.22% ⚠️ 13 Missing
arg-parsing.ts 90.00% ⚠️ 12 Missing
dsn-cache.ts 94.62% ⚠️ 12 Missing
code-scanner.ts 96.25% ⚠️ 12 Missing
logout.ts 56.00% ⚠️ 11 Missing
token.ts 52.17% ⚠️ 11 Missing
fix.ts 83.61% ⚠️ 10 Missing
qrcode.ts 33.33% ⚠️ 10 Missing
fs-utils.ts 57.14% ⚠️ 9 Missing
view.ts 94.70% ⚠️ 7 Missing
project-root.ts 97.73% ⚠️ 7 Missing
version-check.ts 91.76% ⚠️ 7 Missing
feedback.ts 84.21% ⚠️ 6 Missing
auth.ts 95.56% ⚠️ 6 Missing
shell.ts 96.23% ⚠️ 6 Missing
app.ts 93.90% ⚠️ 5 Missing
setup.ts 97.84% ⚠️ 4 Missing
list.ts 97.33% ⚠️ 4 Missing
index.ts 95.96% ⚠️ 4 Missing
helpers.ts 84.62% ⚠️ 4 Missing
project-aliases.ts 97.40% ⚠️ 2 Missing
project-root-cache.ts 96.92% ⚠️ 2 Missing
output.ts 89.47% ⚠️ 2 Missing
alias.ts 99.42% ⚠️ 1 Missing
completions.ts 99.37% ⚠️ 1 Missing
env-file.ts 99.19% ⚠️ 1 Missing
parser.ts 98.63% ⚠️ 1 Missing
colors.ts 98.21% ⚠️ 1 Missing
trace.ts 99.16% ⚠️ 1 Missing
region.ts 97.30% ⚠️ 1 Missing
helpers.ts 97.62% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    68.44%    70.32%    +1.88%
==========================================
  Files          109       109         —
  Lines        13249     13361      +112
  Branches         0         0         —
==========================================
+ Hits          9068      9396      +328
- Misses        4181      3965      -216
- Partials         0         0         —

Generated by Codecov Action

@BYK BYK marked this pull request as ready for review February 10, 2026 00:48
@BYK BYK force-pushed the fix/project-list-pagination branch from d09e97c to 8ca6cff Compare February 10, 2026 10:46
@BYK BYK changed the base branch from feat/profile-command to main February 10, 2026 10:46
BYK added 10 commits February 10, 2026 20:54
- Follow API cursor pagination so --limit >100 actually works
- Add org/ prefix syntax to list projects for a specific org
- Add org/project syntax to show a single project directly
- Add --cursor/--prev flags for manual page navigation
- Add pagination_cursors table (schema v5) with composite PK
- Cache cursors per (command_key, context) for independent paging
- Clear pagination cursors on auth logout
- Regenerate SKILL.md for updated command help
- Property-based tests for parseLinkHeader (RFC 5988 Link header parsing)
- Model-based tests for pagination cursor storage (composite PK, TTL, upsert)
- Unit + property tests for project list helpers (buildContextKey, filterByPlatform, resolveCursor)
- Handler tests for handleExplicit, handleOrgAll, handleProjectSearch with fetch mocking
- Verify clearAuth cross-cutting invariant clears pagination cursors
- Export parseLinkHeader and project list helpers for testability
…ONFIG_DIR

Falls back to creating a temp directory when the env var is not set,
which can happen due to test file ordering and worker isolation in CI.
…AutoDetect

- Test displayProjectTable (table formatting orchestrator)
- Test fetchOrgProjects (attaches orgSlug context)
- Test fetchOrgProjectsSafe (swallows non-auth errors, propagates AuthError)
- Test fetchAllOrgProjects (fans out across orgs, skips access errors)
- Test handleAutoDetect (auto-detect mode with platform filter, limit, JSON output)
- Export additional functions from list.ts for testability
Address review comments:
- Use single-page listProjectsPaginated for single-org auto-detect without
  platform filter, avoiding unnecessary full pagination (up to 5000 items)
- Remove no-op identity mapping in handleProjectSearch
…-duplicate ProjectWithOrg

Address review comments:
- Track hasMore from listProjectsPaginated response in auto-detect fast path
  so truncation message appears when server has more results
- Make ProjectWithOrg in list.ts private to eliminate duplicate exported type
  with conflicting orgSlug optionality (canonical export in api-client.ts)
…earch

handleProjectSearch now shows 'No project X found matching platform Y' when
projects exist but are filtered out, matching handleExplicit behavior.
Previously it misleadingly said 'No project X found in any accessible org.'
…ojects

findProjectsBySlug now calls getProject(org, slug) per org (1 API call each)
instead of listProjects which auto-paginates up to 50 pages per org.
For a user with 5 orgs, this reduces worst-case from ~250 API calls to 5.
… listProjects

Tests now mock /projects/{org}/{slug}/ (direct lookup) instead of
/organizations/{org}/projects/ (list all) to match the implementation change.
BYK added 3 commits February 10, 2026 20:54
Both are only used internally within list.ts — no external imports exist.
…rove fast-path truncation message

Address two BugBot review comments:

1. Test helpers in schema.test.ts and fix.test.ts now use hand-written DDL
   for pagination_cursors with the correct composite PRIMARY KEY
   (command_key, context), matching production behavior. Previously the
   auto-generated DDL from EXPECTED_TABLES lacked the composite PK.

2. Fast-path truncation message now suggests 'sentry project list <org>/'
   for paginated results instead of '--limit', since the API caps per_page
   at 100 and increasing --limit beyond that won't fetch more data.
handleProjectSearch was accepting flags.limit but never applying it,
displaying all matches regardless. Now slices results to flags.limit
and shows a truncation message when matches exceed the limit.

Also applies limit to JSON output for consistency with handleAutoDetect
and handleOrgAll.
@BYK BYK force-pushed the fix/project-list-pagination branch from 246f781 to 4b056d5 Compare February 10, 2026 20:55
…dRequestPaginated

orgScopedRequest now delegates to orgScopedRequestPaginated and discards
the pagination metadata, eliminating duplicated org-slug extraction,
dynamic import, and region resolution boilerplate.
…tion_cursors to test coverage

- Reorder TABLE_SCHEMAS.pagination_cursors columns to match
  PAGINATION_CURSORS_DDL: command_key, context, cursor, expires_at
- Add 'pagination_cursors' to expectedTableNames in schema.test.ts
  so the test catches accidental removal of the table from the schema
…nation types, replace regexes

- buildContextKey: use type:<kind>[:<arg>] notation (type:org:X, type:auto, etc.)
- apiRequestToRegion: always return { data, headers }, remove wrapper
- PaginatedResponse: remove redundant hasMore field, derive from nextCursor
- parseLinkHeader: replace regexes with extractLinkAttr string parsing
- MAX_PAGINATION_PAGES: add JSDoc rationale + SENTRY_MAX_PAGINATION_PAGES env override
- CUSTOM_DDL_TABLES: add JSDoc explaining composite PK limitation
- listCommand docs: add --platform, --limit, --json examples
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

BYK added 2 commits February 13, 2026 11:17
Add compositePrimaryKey field to TableSchema so columnDefsToDDL can emit
table-level PRIMARY KEY constraints. This eliminates all special-casing
for pagination_cursors: CUSTOM_DDL_TABLES, PAGINATION_CURSORS_DDL,
repairPaginationCursorsTable, and the hand-written DDL in test files.

Net -67 lines of code removed.
…message

- Lowercase platform in buildContextKey so --platform Python and
  --platform python resolve to the same cursor cache entry
- When platform filter produces no results and there are no more pages,
  show "No projects matching platform 'X'" instead of the misleading
  "No projects found in organization"
…pollution

Three test files (version-check, install-info, project-cache) were
deleting process.env.SENTRY_CONFIG_DIR in afterEach without saving
the original value set by preload.ts. When Bun's test runner shares
a process across files, this poisons the env for subsequent tests
that capture the var at module load time.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

When --platform is active in org-all mode, the next-page hints now
include the flag so that following the hint preserves the filter
and matches the correct cursor context key.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

…orrectly

- Extract fetchPaginatedSafe() to handle non-auth API errors (403,
  network) in the single-org fast path, matching fetchOrgProjectsSafe
  behavior. Reduces handleAutoDetect complexity below lint threshold.
- Fix createIsolatedDbContext cleanup to restore original env var value
  (including undefined) instead of leaking fallback path.
- Add tests for fast-path error handling (non-auth swallowed, AuthError
  propagated).
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

…nation-v2

# Conflicts:
#	test/lib/db/install-info.test.ts
#	test/lib/db/project-cache.test.ts
#	test/lib/version-check.test.ts
@BYK BYK force-pushed the fix/project-list-pagination branch from b576c7a to 1085d5a Compare February 13, 2026 17:13
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

…nation-v2

# Conflicts:
#	src/lib/api-client.ts
#	src/lib/region.ts
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

findProjectsBySlug now uses getProject (SDK retrieveAProject) per org
instead of listing all projects. The mock was returning an array for
the /projects/{org}/{project}/ endpoint, causing the SDK to parse it
incorrectly. Return 404 for non-existent project detail requests.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

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.

1 participant