Skip to content

feat(mail): add --page-token and --page-size to mail +triage#301

Merged
haidaodashushu merged 8 commits intomainfrom
feat/mail-triage-pagination
Apr 9, 2026
Merged

feat(mail): add --page-token and --page-size to mail +triage#301
haidaodashushu merged 8 commits intomainfrom
feat/mail-triage-pagination

Conversation

@haidaodashushu
Copy link
Copy Markdown
Collaborator

@haidaodashushu haidaodashushu commented Apr 7, 2026

Summary

  • Add --page-token and --page-size flags to mail +triage for external pagination control
  • Token carries search: or list: prefix to identify API path, with strict validation (conflicting params fail fast, bare tokens rejected)
  • JSON/data output now returns { messages, total, has_more, page_token } object; table shows next-page hint on stderr
  • Update skill reference doc with new flags, output format, and usage examples

Test plan

  • Unit tests for resolveTriagePath: search/list prefix routing, bare token rejection, conflict detection
  • Unit tests for resolveTriagePageSize: --page-size priority over --max, clamping
  • DryRun tests: page-token passed to API params, path selection with prefixes, error cases
  • Manual E2E: list path pagination (10+5+10+10+5=40) matches --max 40 baseline
  • Manual E2E: search path pagination (10+10+10=30) matches --query "周报" --max 30 baseline
  • Manual E2E: search token continuation without --query works
  • All existing mail package tests pass (go test ./shortcuts/mail/...)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added --page-size (alias for --max; takes precedence and is clamped) and --page-token to resume pagination (tokens require path prefix).
  • Behavior Changes

    • json/data now return a pagination object (messages, total, has_more, page_token); table still prints rows and now shows a conditional “next page” hint.
    • Pagination tokens validated for search vs list compatibility; Dry-run validates and propagates tokens.
  • Documentation

    • Updated mail triage docs and jq examples to show paged responses and continuation usage.
  • Tests

    • Expanded tests for pagination, token parsing/validation, flag precedence, and DryRun behavior.

…il +triage

Support external pagination for mail +triage with two new flags:
- --page-token: resume from a previous response's page token
- --page-size: alias for --max

Token carries a "search:" or "list:" prefix to identify the API path,
with strict validation: conflicting parameters (e.g. list: token with
--query) fail fast, and bare tokens without prefix are rejected.

JSON/data output now returns an object with messages, total, has_more,
and page_token fields. Table output shows next-page hint on stderr.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 7, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds pagination to the mail triage CLI: new --page-size/--page-token flags, page-token parsing/validation and path resolution, pagination-aware JSON/data output (messages/total/has_more/page_token), continued paging loops with next-page hints in table mode, plus tests and docs updates.

Changes

Cohort / File(s) Summary
CLI implementation
shortcuts/mail/mail_triage.go
Adds flags --page-size and --page-token; changes --format json/--format data to emit a pagination object (messages, total, has_more, page_token); implements triagePageToken type, parseTriagePageToken, encodeTriagePageToken, resolveTriagePath, and resolveTriagePageSize; reworks pagination loop to track hasMore/nextPageToken, ensures non-nil messages, and adjusts DryRun to validate/propagate parsed page tokens.
Unit tests
shortcuts/mail/mail_triage_test.go
Adds extensive tests for page-size resolution (defaults, precedence, clamping), page-token parsing/encoding/validation (prefix rules, colon handling), resolveTriagePath rules, DryRun propagation of page_size/page_token and search/list behaviors, and flag-definition checks for page-token, page-size, and max.
Docs
skills/lark-mail/references/lark-mail-triage.md
Updates examples and usage: --format json/data structure now includes pagination metadata; shows jq examples using .messages[]; documents --page-size (alias for --max) and --page-token prefix rules and continuation examples; documents search-pagination caveats and table-mode next-page hints.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as "User"
  participant CLI as "mail triage CLI"
  participant Parser as "Page-token parser"
  participant API as "Mail API (search/list)"
  participant Formatter as "Output formatter"

  User->>CLI: run command (--page-size?, --page-token?, --query/--filter?)
  CLI->>Parser: parse/validate --page-token rgba(200,200,255,0.5)
  Parser-->>CLI: (path, rawToken) or error rgba(200,200,255,0.5)
  CLI->>API: call (path, page_size, page_token, query/filter) rgba(200,255,200,0.5)
  API-->>CLI: response (messages, total, has_more, page_token) rgba(255,200,200,0.5)
  CLI->>Formatter: format output (json|data|table) and include next-page hint if has_more rgba(255,200,200,0.5)
  Formatter-->>User: display results and page_token/hint
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • zero-my

Poem

"I hop through inbox lanes with glee,
tokens tucked like keys in me.
Pages stretch and pages flow,
I fetch the next — off I go! 🐇"

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding pagination support via --page-token and --page-size flags to the mail triage command.
Description check ✅ Passed The description covers all required template sections (Summary, Changes, Test Plan, Related Issues) with substantive details about implementation, validation approach, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/mail-triage-pagination

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added domain/mail PR touches the mail domain size/M Single-domain feat or fix with limited business impact labels Apr 7, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
skills/lark-mail/references/lark-mail-triage.md (1)

103-106: Add language specifier to fenced code block.

The code block is missing a language identifier. Since this shows shell/terminal output, use an appropriate specifier.

-```
+```text
 15 message(s)
 next page: mail +triage --page-token 'list:FfccvoqPd...' ...
 tip: use mail +message --message-id <id> to read full content
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/lark-mail/references/lark-mail-triage.md` around lines 103 - 106, The
fenced code block that currently contains the terminal output starting with "15
message(s)" should include a language specifier to indicate plain text; update
the triple-backtick fence for that block to use a language tag such as "text"
(e.g., change ``` to ```text) so the shell/terminal output is rendered
correctly.
shortcuts/mail/mail_triage_test.go (1)

1052-1060: Duplicate test coverage for bare token rejection.

TestResolveTriagePathBareTokenRejected (lines 1052-1060) and TestPageTokenBareTokenRejected (lines 1097-1105) test the same scenario. Consider consolidating to reduce test duplication.

Also applies to: 1097-1105

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/mail/mail_triage_test.go` around lines 1052 - 1060, Two tests
duplicate the same scenario: TestResolveTriagePathBareTokenRejected and
TestPageTokenBareTokenRejected both assert that a bare token without a prefix
causes an error; consolidate by removing or merging one of them. Keep a single
test (either TestResolveTriagePathBareTokenRejected or
TestPageTokenBareTokenRejected) that calls resolveTriagePath("baretoken123", "",
triageFilter{}) and asserts err != nil and that err.Error() contains "prefix";
update or remove the duplicate test accordingly and ensure any helper names
referenced (resolveTriagePath, TestResolveTriagePathBareTokenRejected,
TestPageTokenBareTokenRejected) are adjusted so there is only one coverage point
for this case.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@shortcuts/mail/mail_triage_test.go`:
- Around line 1052-1060: Two tests duplicate the same scenario:
TestResolveTriagePathBareTokenRejected and TestPageTokenBareTokenRejected both
assert that a bare token without a prefix causes an error; consolidate by
removing or merging one of them. Keep a single test (either
TestResolveTriagePathBareTokenRejected or TestPageTokenBareTokenRejected) that
calls resolveTriagePath("baretoken123", "", triageFilter{}) and asserts err !=
nil and that err.Error() contains "prefix"; update or remove the duplicate test
accordingly and ensure any helper names referenced (resolveTriagePath,
TestResolveTriagePathBareTokenRejected, TestPageTokenBareTokenRejected) are
adjusted so there is only one coverage point for this case.

In `@skills/lark-mail/references/lark-mail-triage.md`:
- Around line 103-106: The fenced code block that currently contains the
terminal output starting with "15 message(s)" should include a language
specifier to indicate plain text; update the triple-backtick fence for that
block to use a language tag such as "text" (e.g., change ``` to ```text) so the
shell/terminal output is rendered correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5898bb3f-2cdc-4b1d-a7ba-a8b3f559a1d3

📥 Commits

Reviewing files that changed from the base of the PR and between 6bc6bb6 and 236249e.

📒 Files selected for processing (3)
  • shortcuts/mail/mail_triage.go
  • shortcuts/mail/mail_triage_test.go
  • skills/lark-mail/references/lark-mail-triage.md

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 7, 2026

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@530fb01ce28739d90656c830b97477622b7879c9

🧩 Skill update

npx skills add larksuite/cli#feat/mail-triage-pagination -y -g

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 7, 2026

Greptile Summary

This PR adds --page-size (alias for --max) and --page-token flags to mail +triage, enabling callers to drive pagination externally. Tokens carry a search:/list: prefix that is validated against the current query/filter params, and --format json/--format data now return a {messages, count, has_more, page_token} envelope instead of a bare array.

Confidence Score: 5/5

Safe to merge; the only new finding is a dead-code guard that has no impact on runtime behavior.

All P0/P1 concerns from prior review rounds have been addressed (whitespace-query edge case is now correctly handled with strings.TrimSpace). The single remaining finding is a logically unreachable error branch in the search: case of resolveTriagePath — the code still behaves correctly (always proceeds on the search path for search: tokens), so this is purely a readability/dead-code issue. Test coverage for the new pagination logic is thorough.

shortcuts/mail/mail_triage.go — the unreachable guard in resolveTriagePath's search: case (line 921–925) can be cleaned up.

Vulnerabilities

No security concerns identified. The token validation rejects bare tokens and unknown prefixes, page-size inputs are clamped, and --query passes through the existing RejectDangerousChars guard.

Important Files Changed

Filename Overview
shortcuts/mail/mail_triage.go Adds --page-size and --page-token flags with token prefix routing, path validation, and paginated JSON envelope output; contains one dead-code error guard in the search: branch of resolveTriagePath.
shortcuts/mail/mail_triage_test.go Comprehensive new tests for token parsing, path resolution, page-size priority, and DryRun propagation; all new code paths are covered.
skills/lark-mail/references/lark-mail-triage.md Documentation updated to match new envelope output shape, new flags, and pagination usage examples; consistent with the implementation.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[mail +triage called] --> B{--page-token provided?}
    B -- No --> C{usesTriageSearchPath?}
    B -- Yes --> D[parseTriagePageToken]
    D --> E{prefix?}
    E -- "search:" --> F[resolveTriagePath: always useSearch=true]
    E -- "list:" --> G{paramWantsSearch?}
    E -- bare/invalid --> H[return error]
    G -- Yes --> I[return error: conflicting params]
    G -- No --> J[useSearch=false]
    C -- Yes --> K[Search API loop]
    F --> K
    C -- No --> L[List API loop]
    J --> L
    K --> M{has_more and loop condition}
    L --> N{has_more and loop condition}
    M --> O[accumulate messages, set hasMore/nextPageToken]
    N --> O
    O --> P{outFormat?}
    P -- "json/data" --> Q["Output: {messages, count, has_more, page_token}"]
    P -- table --> R[Print table + stderr hint with next-page token]
Loading

Reviews (7): Last reviewed commit: "fix(mail): improve dry-run desc when usi..." | Re-trigger Greptile

Comment thread shortcuts/mail/mail_triage.go
Comment thread shortcuts/mail/mail_triage.go Outdated
Copy link
Copy Markdown
Collaborator

@chanthuang chanthuang left a comment

Choose a reason for hiding this comment

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

Review 基于 MR Tracker 处理意见

功能设计合理,token 前缀路由(search:/list:)和冲突校验逻辑严谨,测试覆盖充分(+345 行测试代码)。但有两个问题建议在合并前解决:

1. [Breaking Change] JSON/data 输出格式从数组变为对象

--format json / --format data 的输出从裸数组:

[{"message_id": "...", ...}]

变为对象:

{"messages": [...], "total": 20, "has_more": true, "page_token": "..."}

这是破坏性变更——现有脚本(如 mail +triage --format json | jq '.[0]')会直接报错。建议:

  • 方案 A:在 PR 描述和 changelog 中明确标注 BREAKING CHANGE
  • 方案 B:仅在传入 --page-token 时返回对象格式,无分页参数时保持原数组输出以向后兼容

2. total 字段名误导

"total": len(messages),

total 的实际值是 len(messages)(当前页返回的条数),而非所有页面的全局总条数。用户很容易将 total 理解为"符合条件的邮件总数"。建议:

  • 改为 countpage_count,语义更准确
  • 或者直接移除——messages 数组的长度已经自明

其余方面评价:

  • resolveTriagePath 的前缀校验逻辑清晰,裸 token 拒绝、前缀与参数冲突检测完备
  • resolveTriagePageSize--page-size 优先于 --max 的设计合理
  • table 格式在 stderr 输出 next page: 提示是良好的 UX 设计
  • 测试覆盖了路径选择、冲突检测、DryRun、flag 定义等关键场景

Co-Authored-By: AI

…ace query edge case

- --format data preserves backward-compatible flat array output
- --format json returns the new envelope object with pagination fields
- Align search: prefix guard with TrimSpace(query) to match usesTriageSearchPath
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 9, 2026

Tip:

Greploop — Automatically fix all review issues by running /greploops in Claude Code. It iterates: fix, push, re-review, repeat until 5/5 confidence.

Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/mail/mail_triage.go`:
- Around line 892-913: resolveTriagePath currently treats prefix-only pageToken
values like "search:" or "list:" as valid, which later become empty continuation
tokens and restart paging; update resolveTriagePath to reject tokens that are
exactly the prefix (or prefix + only whitespace) by checking pageToken after
trimming the prefix and whitespace and returning an error for empty continuation
payloads, preserving the existing prefix-specific error messages and using the
same symbols (resolveTriagePath, pageToken, usesTriageSearchPath,
triageQueryFilterFields) so callers fail fast on invalid prefixed tokens.

In `@skills/lark-mail/references/lark-mail-triage.md`:
- Around line 102-107: Add a language tag to the fenced code block that starts
with the lines "15 message(s)" to satisfy markdownlint rule MD040; locate the
fenced block in skills/lark-mail/references/lark-mail-triage.md (the block that
shows "next page: mail +triage --page-token ...") and change the opening fence
to include a language identifier (e.g., text) so the block becomes a fenced code
block with a language tag.
- Around line 34-36: The caption "data 格式方便 jq 处理" mismatches the example which
uses "--format json"; update the caption or the example so they match: either
change the caption to mention "json 格式方便 jq 处理" to align with the command
"lark-cli mail +triage --format json | jq '.messages[].subject'", or change the
example command to use the "data" format (e.g., "lark-cli mail +triage --format
data ...") and adjust the jq filter accordingly; ensure the caption and the
command/example text refer to the same format.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: d00e0918-199d-4b5e-b98d-a313445a9371

📥 Commits

Reviewing files that changed from the base of the PR and between 236249e and 8faf991.

📒 Files selected for processing (2)
  • shortcuts/mail/mail_triage.go
  • skills/lark-mail/references/lark-mail-triage.md

Comment thread shortcuts/mail/mail_triage.go Outdated
Comment thread skills/lark-mail/references/lark-mail-triage.md Outdated
Comment thread skills/lark-mail/references/lark-mail-triage.md Outdated
- Remove page_size encoding from token (search:abc → not search:5:abc)
  The search API token is a session cursor; page_size only controls how
  many items to return, not the cursor position. Encoding page_size
  caused data loss when users changed --page-size between requests.
- Token format is now simply "search:<raw>" / "list:<raw>"
- Add parseTriagePageToken/encodeTriagePageToken helpers for clean
  token handling with proper validation
- next page hint in table output now includes --query and --filter
  for easy copy-paste continuation
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
shortcuts/mail/mail_triage_test.go (2)

1185-1195: Use structured DryRun assertions instead of string contains + ignored marshal error.

Both tests ignore json.Marshal errors and assert "filter_error" via substring matching. Prefer decoding once (or reusing dryRunAPIsForMailTriageTest-style helper) and asserting the actual field; this improves reliability and diagnostics.

Also applies to: 1279-1284

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/mail/mail_triage_test.go` around lines 1185 - 1195, The test
TestMailTriageDryRunBarePageTokenErrors currently ignores json.Marshal errors
and asserts via strings.Contains; change it to decode the DryRun result into the
DryRun struct (or reuse the existing helper dryRunAPIsForMailTriageTest) instead
of marshaling to JSON, check and handle the marshal/unmarshal error, and assert
the specific field (e.g., DryRun.FilterError or the equivalent field on the
returned struct) equals the expected "filter_error". Apply the same change to
the other test referenced around lines 1279-1284 so both tests use structured
assertions and fail with clear error messages when (un)marshaling or the field
assertion fails.

1014-1080: Consolidate duplicated resolveTriagePath test coverage.

These two blocks cover almost the same scenarios (search/list prefix routing, conflicts, bare token, empty token fallback). Please collapse into one table-driven suite to reduce maintenance noise.

Also applies to: 1200-1257

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/mail/mail_triage_test.go` around lines 1014 - 1080, Consolidate the
duplicated resolveTriagePath tests into a single table-driven test that iterates
cases describing token input, query string, triageFilter, expected useSearch
bool, and expected error presence; replace the separate
TestResolveTriagePathSearchTokenContinuation,
TestResolveTriagePathListTokenConflictsWithQuery,
TestResolveTriagePathListTokenConflictsWithSearchFilter,
TestResolveTriagePathListTokenWithListFilter,
TestResolveTriagePathBareTokenRejected and TestResolveTriagePathEmptyToken with
one TestResolveTriagePath_TableDriven that parses tokens with
parseTriagePageToken (or constructs an empty triagePageToken for the empty-token
case), calls resolveTriagePath, and asserts both error existence and useSearch
outcome, and apply the same refactor to the similar block around the other
occurrence (lines noted) to remove duplication and keep each scenario as one
table entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/mail/mail_triage_test.go`:
- Around line 972-977: The test is validating fallback behavior because
runtimeForMailTriageTest registers int flags with default 0; update the test or
helper so it verifies the actual flag default instead of normalize behavior.
Change runtimeForMailTriageTest (or the TestResolveTriagePageSizeDefaultMax
setup) to register the --max flag with the MailTriage default (20) rather than
0, or explicitly set the flag value to 20 before calling resolveTriagePageSize;
ensure you modify code paths in runtimeForMailTriageTest and the
TestResolveTriagePageSizeDefaultMax test that reference resolveTriagePageSize
and normalizeTriageMax so the test asserts the flag default behavior.

---

Nitpick comments:
In `@shortcuts/mail/mail_triage_test.go`:
- Around line 1185-1195: The test TestMailTriageDryRunBarePageTokenErrors
currently ignores json.Marshal errors and asserts via strings.Contains; change
it to decode the DryRun result into the DryRun struct (or reuse the existing
helper dryRunAPIsForMailTriageTest) instead of marshaling to JSON, check and
handle the marshal/unmarshal error, and assert the specific field (e.g.,
DryRun.FilterError or the equivalent field on the returned struct) equals the
expected "filter_error". Apply the same change to the other test referenced
around lines 1279-1284 so both tests use structured assertions and fail with
clear error messages when (un)marshaling or the field assertion fails.
- Around line 1014-1080: Consolidate the duplicated resolveTriagePath tests into
a single table-driven test that iterates cases describing token input, query
string, triageFilter, expected useSearch bool, and expected error presence;
replace the separate TestResolveTriagePathSearchTokenContinuation,
TestResolveTriagePathListTokenConflictsWithQuery,
TestResolveTriagePathListTokenConflictsWithSearchFilter,
TestResolveTriagePathListTokenWithListFilter,
TestResolveTriagePathBareTokenRejected and TestResolveTriagePathEmptyToken with
one TestResolveTriagePath_TableDriven that parses tokens with
parseTriagePageToken (or constructs an empty triagePageToken for the empty-token
case), calls resolveTriagePath, and asserts both error existence and useSearch
outcome, and apply the same refactor to the similar block around the other
occurrence (lines noted) to remove duplication and keep each scenario as one
table entry.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0fd0bd23-0d21-4b7e-a455-1d1b8c53baf5

📥 Commits

Reviewing files that changed from the base of the PR and between 8faf991 and 613535a.

📒 Files selected for processing (2)
  • shortcuts/mail/mail_triage.go
  • shortcuts/mail/mail_triage_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/mail/mail_triage.go

Comment thread shortcuts/mail/mail_triage_test.go
…arch pagination note

- Separate --format json (object with pagination) and --format data (array) examples
- Update table next-page hint example to show --query/--filter inclusion
- Add search pagination caveat about cross-session result ordering
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
skills/lark-mail/references/lark-mail-triage.md (2)

117-117: ⚠️ Potential issue | 🟡 Minor

Add a language identifier to the fenced block.

The code fence at Line 117 is missing a language tag and triggers markdownlint MD040.

Suggested fix
-```
+```text
 15 message(s)
 next page: mail +triage --query '合同审批' --page-token 'search:abc123...'
 tip: use mail +message --message-id <id> to read full content
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @skills/lark-mail/references/lark-mail-triage.md at line 117, The fenced code
block containing the lines starting with "15 message(s)" and "next page: mail
+triage --query '合同审批' --page-token 'search:abc123...'" is missing a language
identifier; update the opening fence from totext (or another appropriate
language like ```bash) so the block becomes a tagged fenced code block and
satisfies markdownlint MD040.


</details>

---

`34-35`: _⚠️ Potential issue_ | _🟡 Minor_

**Fix the format caption/example mismatch.**

Line 34 says `data` format, but Line 35 demonstrates `--format json` with `.messages[]`. Please align the caption and command to the same format.
 

<details>
<summary>Suggested doc fix</summary>

```diff
-# data 格式方便 jq 处理
+# json 格式可配合 jq 处理(data 格式则直接是数组)
 lark-cli mail +triage --format json | jq '.messages[].subject'
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@skills/lark-mail/references/lark-mail-triage.md` around lines 34 - 35, The
caption " # data 格式方便 jq 处理" conflicts with the example command using "--format
json"; update the caption to match the command (e.g., change the heading to
"json 格式方便 jq 处理") or alternatively change the command to use "--format data"
and adjust the jq expression; specifically edit the heading text "data 格式方便 jq
处理" to "json 格式方便 jq 处理" (or make the command use --format data and appropriate
jq) so the caption and the example "lark-cli mail +triage --format json | jq
'.messages[].subject'" are consistent.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @skills/lark-mail/references/lark-mail-triage.md:

  • Line 117: The fenced code block containing the lines starting with "15
    message(s)" and "next page: mail +triage --query '合同审批' --page-token
    'search:abc123...'" is missing a language identifier; update the opening fence
    from totext (or another appropriate language like ```bash) so the block
    becomes a tagged fenced code block and satisfies markdownlint MD040.
  • Around line 34-35: The caption " # data 格式方便 jq 处理" conflicts with the example
    command using "--format json"; update the caption to match the command (e.g.,
    change the heading to "json 格式方便 jq 处理") or alternatively change the command to
    use "--format data" and adjust the jq expression; specifically edit the heading
    text "data 格式方便 jq 处理" to "json 格式方便 jq 处理" (or make the command use --format
    data and appropriate jq) so the caption and the example "lark-cli mail +triage
    --format json | jq '.messages[].subject'" are consistent.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `bc9a5fa7-fe89-4222-9f2a-79c2fb869b8e`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 613535a88a6b30927b93a7521c21d84488f5f00d and 99dfebde0b087dbb780d9174feb36a892e504650.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `skills/lark-mail/references/lark-mail-triage.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
shortcuts/mail/mail_triage.go (1)

903-906: ⚠️ Potential issue | 🟡 Minor

拒绝仅前缀的 --page-token,避免静默回到第一页。

parseTriagePageToken 当前会接受 search:/list:(空 raw token);随后 Line 904 把它当作“无 token”处理,可能导致静默重启分页。

Suggested fix
 func resolveTriagePath(parsed triagePageToken, query string, filter triageFilter) (useSearch bool, err error) {
-	if parsed.RawToken == "" {
+	if parsed.Path == "" && parsed.RawToken == "" {
 		return usesTriageSearchPath(query, filter), nil
 	}
 	paramWantsSearch := usesTriageSearchPath(query, filter)
@@
 func parseTriagePageToken(token string) (triagePageToken, error) {
+	token = strings.TrimSpace(token)
 	if token == "" {
 		return triagePageToken{}, nil
 	}
 	idx := strings.IndexByte(token, ':')
@@
 	path := token[:idx]
-	raw := token[idx+1:]
+	raw := strings.TrimSpace(token[idx+1:])
 	if path != "search" && path != "list" {
 		return triagePageToken{}, fmt.Errorf("invalid --page-token: must start with 'search:' or 'list:' prefix, got %q", path)
 	}
+	if raw == "" {
+		return triagePageToken{}, fmt.Errorf("invalid --page-token: missing token after %q prefix", path+":")
+	}
 	return triagePageToken{Path: path, RawToken: raw}, nil
 }

Also applies to: 941-955

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/mail/mail_triage.go` around lines 903 - 906, resolveTriagePath
treats a parsed triagePageToken with an empty RawToken (e.g., when
parseTriagePageToken accepted only the prefix "search:" or "list:") as "no
token" and falls back to usesTriageSearchPath(query, filter), which silently
resets pagination; change resolveTriagePath to reject/return an error when
parsed.RawToken is empty but the original token had a prefix (i.e., ensure
parseTriagePageToken signals prefix-only tokens as invalid) so callers (or
resolveTriagePath) do not treat prefix-only page tokens as absent; update
resolveTriagePath and the analogous logic around the other branch (lines
~941-955) to validate triagePageToken.RawToken and return an explicit error
instead of defaulting to usesTriageSearchPath.
skills/lark-mail/references/lark-mail-triage.md (2)

109-113: ⚠️ Potential issue | 🟡 Minor

为该 fenced code block 添加语言标记(MD040)。

当前代码块缺少语言标签,会触发 markdownlint 的 MD040

Suggested doc fix
-```
+```text
 15 message(s)
 next page: mail +triage --query '合同审批' --page-token 'search:abc123...'
 tip: use mail +message --message-id <id> to read full content
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @skills/lark-mail/references/lark-mail-triage.md around lines 109 - 113, The
fenced code block that currently shows the sample output starting with "15
message(s)" is missing a language tag and triggers markdownlint MD040; update
that fenced block (the one containing "15 message(s)\nnext page: mail +triage
--query '合同审批' --page-token 'search:abc123...'\ntip: use mail +message
--message-id to read full content") by adding a language identifier (for
example, use ```text) immediately after the opening backticks so the block
becomes a labeled code fence.


</details>

---

`34-35`: _⚠️ Potential issue_ | _🟡 Minor_

**修正示例标题与命令格式不一致。**

Line 34 写的是 “data 格式”,但 Line 35 示例是 `--format json` 且使用 `.messages[]`,两者语义不一致。

 

<details>
<summary>Suggested doc fix</summary>

```diff
-# data 格式方便 jq 处理
+# json 格式方便 jq 处理
 lark-cli mail +triage --format json | jq '.messages[].subject'
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@skills/lark-mail/references/lark-mail-triage.md` around lines 34 - 35, The
title "data 格式方便 jq 处理" and the example command "lark-cli mail +triage --format
json | jq '.messages[].subject'" are inconsistent; either change the title to
"json 格式方便 jq 处理" to match the command, or change the command to use the data
format (e.g. replace "--format json" with "--format data" and adjust the jq
expression accordingly); update whichever text you choose so the header and the
example command consistently refer to the same format.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @shortcuts/mail/mail_triage.go:

  • Around line 290-295: 当前将 query、filterStr 和 nextPageToken 直接拼入单引号的 shell 示例中(见
    hint.WriteString(fmt.Sprintf(" --query '%s'", query)),
    hint.WriteString(fmt.Sprintf(" --filter '%s'", filterStr)) 和
    hint.WriteString(fmt.Sprintf(" --page-token '%s'",
    nextPageToken))),当这些值包含单引号时会破坏命令;请新增一个小的 shell-escape 辅助函数(例如 shellEscape(s
    string))用于把任意字符串安全地转换为 shell 字面量(典型方法是用单引号包裹并将内部单引号替换为安全序列),然后在构建提示时用
    shellEscape(query)、shellEscape(filterStr) 和 shellEscape(nextPageToken) 替换当前的直接
    fmt.Sprintf 拼接,以保证复制的命令在包含引号时仍然安全可用。

Duplicate comments:
In @shortcuts/mail/mail_triage.go:

  • Around line 903-906: resolveTriagePath treats a parsed triagePageToken with an
    empty RawToken (e.g., when parseTriagePageToken accepted only the prefix
    "search:" or "list:") as "no token" and falls back to
    usesTriageSearchPath(query, filter), which silently resets pagination; change
    resolveTriagePath to reject/return an error when parsed.RawToken is empty but
    the original token had a prefix (i.e., ensure parseTriagePageToken signals
    prefix-only tokens as invalid) so callers (or resolveTriagePath) do not treat
    prefix-only page tokens as absent; update resolveTriagePath and the analogous
    logic around the other branch (lines ~941-955) to validate
    triagePageToken.RawToken and return an explicit error instead of defaulting to
    usesTriageSearchPath.

In @skills/lark-mail/references/lark-mail-triage.md:

  • Around line 109-113: The fenced code block that currently shows the sample
    output starting with "15 message(s)" is missing a language tag and triggers
    markdownlint MD040; update that fenced block (the one containing "15
    message(s)\nnext page: mail +triage --query '合同审批' --page-token
    'search:abc123...'\ntip: use mail +message --message-id to read full
    content") by adding a language identifier (for example, use ```text) immediately
    after the opening backticks so the block becomes a labeled code fence.
  • Around line 34-35: The title "data 格式方便 jq 处理" and the example command
    "lark-cli mail +triage --format json | jq '.messages[].subject'" are
    inconsistent; either change the title to "json 格式方便 jq 处理" to match the command,
    or change the command to use the data format (e.g. replace "--format json" with
    "--format data" and adjust the jq expression accordingly); update whichever text
    you choose so the header and the example command consistently refer to the same
    format.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `dbd70deb-eb31-4147-98b1-e3d8248cfebe`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 99dfebde0b087dbb780d9174feb36a892e504650 and b273ad55351944b4f3ecea6f881f8d0cea7fa11f.

</details>

<details>
<summary>📒 Files selected for processing (2)</summary>

* `shortcuts/mail/mail_triage.go`
* `skills/lark-mail/references/lark-mail-triage.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread shortcuts/mail/mail_triage.go Outdated
- Reject empty prefixed tokens (search: / list:) in parseTriagePageToken
- Shell-escape query/filter in next-page hint to handle single quotes
- Fix doc caption mismatch (data → json/data) and add language tag to code block
- Fix test comment for TestResolveTriagePageSizeDefaultMax
total was misleading — it represented the current page count, not the
global total. Renamed to count to match len(messages) semantics.
@haidaodashushu haidaodashushu merged commit fd9ee6a into main Apr 9, 2026
16 checks passed
@haidaodashushu haidaodashushu deleted the feat/mail-triage-pagination branch April 9, 2026 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/mail PR touches the mail domain size/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants