Skip to content

feat(im): add +chat-list and --exclude-muted to filter muted chats#820

Merged
YangJunzhou-01 merged 1 commit into
larksuite:mainfrom
shifengjuan-dev:feat/im-chats-filter-muted
May 14, 2026
Merged

feat(im): add +chat-list and --exclude-muted to filter muted chats#820
YangJunzhou-01 merged 1 commit into
larksuite:mainfrom
shifengjuan-dev:feat/im-chats-filter-muted

Conversation

@shifengjuan-dev

@shifengjuan-dev shifengjuan-dev commented May 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add im +chat-list shortcut wrapping GET /open-apis/im/v1/chats (previously not exposed via lark-cli).
  • Add --exclude-muted to both +chat-search and +chat-list: client-side filter that calls POST /open-apis/im/v1/chat_user_setting/batch_get_mute_status after each page and drops is_muted=true chats.
  • Introduce shortcuts/im/mute_filter.go with pure helpers and an orchestrator (MaybeApplyMuteFilter) shared by both shortcuts.

Design highlights

  • Pure A (transparent reporting, no top-up). Filtered pages may be smaller than --page-size; the JSON output adds a filter sub-object with applied/skipped/fetched_count/returned_count/filtered_count/hint so AI/scripts can chain page_token.
  • Invariant: fetched_count == returned_count + filtered_count always holds.
  • Bot identity (--as bot): batch_get_mute_status is UAT-only, so the filter is skipped with filter.skipped=true, skip_reason="bot_identity_no_mute_data". All chats returned unfiltered.
  • --search-types public_not_joined alone: pre-skipped with skip_reason="all_non_member_search_types" (the batch call would 100% return not_a_member).
  • Non-member chats (e.g. default query containing public_not_joined results): silently retained, not counted in filtered_count; surfaced in the hint text only.
  • No request-body pollution: --exclude-muted never injects search_types or any other field into the search/list request. Verified via dry-run tests.
  • No client-side metrics: server-side BatchGetChatMuteStatus already has metrics (mute_status.go:60-62). CLI does not duplicate.

Output schema (only when --exclude-muted is set)

{
  "chats": [...],
  "filter": {
    "applied": "exclude_muted",
    "skipped": false,
    "fetched_count": 20,
    "returned_count": 19,
    "filtered_count": 1,
    "hint": "Filtered out 1 muted chat(s) on this page (19 remaining, including 2 non-member public group(s)); use --page-token to fetch more."
  }
}

Hint is shown in --format json (field) and --format pretty (line below summary). Not shown in --format table/ndjson/csv — consistent with the existing pagination hint behavior.

Test plan

  • go test ./shortcuts/im/... — passes
  • go build ./... — clean
  • go vet ./... — clean
  • +chat-list --dry-run — endpoint + params correct
  • +chat-search --query foo --exclude-muted --dry-run — request body unchanged, no search_types injection
  • +chat-search --search-types public_not_joined --exclude-muted --dry-runsearch_types present as user requested, no auto-injection
  • +chat-list --help exposes --exclude-muted with correct description
  • Live UAT call against tenant once batch_get_mute_status is GA (currently UAT-only)
  • Live --as bot call confirms filter.skipped=true with bot_identity_no_mute_data

Risks

  • batch_get_mute_status is currently UAT-only (TAT/bot rejected at the API gateway). The CLI handles this gracefully (bot identity skips the filter), but the API itself must be GA before this feature is broadly usable.
  • im:chat:read scope is assumed to cover chat_user_setting reads. If the gateway requires a separate scope, users will see 99991679/99991672 and we will need a follow-up to add the right scope.
  • Coupling to v2 search response shape: implementation reads meta_data.chat_id from each item; if the v2 search response schema changes the wrapping, the filter helper needs updating.

Spec docs

  • Design: docs/specs/2026-05-09-im-chats-filter-muted-design.md
  • Plan: docs/specs/2026-05-09-im-chats-filter-muted-plan.md

These reference the earlier exploration at docs/specs/2026-04-28-search-filter-muted-chats-design.md — this PR is the CLI-side variant (option D — pure transparent reporting) that does not block on the search-team-side option B.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added +chat-list to list group chats with sorting, pagination, and user-ID type selection.
    • Added --exclude-muted (user identity only) to +chat-search and +chat-list to client-side filter muted/DND chats and surface a filter hint.
  • Documentation

    • Added docs for +chat-list and updated +chat-search docs with mute-filter behavior, JSON filter shape, and usage examples.
  • Tests

    • Added comprehensive tests covering list/search dry-run, validate bounds, and mute-filter behavior and hints.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown

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 a new +chat-list IM shortcut and implements a reusable client-side --exclude-muted mute-filtering system used by both chat-search and chat-list; includes validation, DryRun behavior, comprehensive tests, and updated documentation.

Changes

IM Chat List and Mute Filtering

Layer / File(s) Summary
Mute Filter Data Model and Constants
shortcuts/im/mute_filter.go
MuteFilterMeta type with applied/skipped status, skip reasons, and counters; batch API path and max batch size constants.
Mute Filter Building Blocks
shortcuts/im/mute_filter.go
BuildMuteFilterHint, BuildBatchGetMuteStatusBody, ParseBatchGetMuteStatusResponse, ExtractChatIDs, MuteFilterMetaToMap, and FetchMuteStatus wrapper with validation and error context.
Core Filter Logic and Orchestration
shortcuts/im/mute_filter.go
ApplyMuteFilter removes muted rows while preserving unknown/absent IDs and counters; MaybeApplyMuteFilter orchestrates skip conditions and batch fetch/apply/hint flow.
Mute Filter Unit Tests
shortcuts/im/mute_filter_test.go
Comprehensive tests for hint generation, batch request/response parsing, filter semantics and counters, ID extraction, meta mapping, orchestrator branches, and FetchMuteStatus edge cases.
Chat List Shortcut Implementation
shortcuts/im/im_chat_list.go
ImChatList shortcut with --user-id-type, --sort-type, --page-size (1–100), --page-token, and --exclude-muted; validation, DryRun, param builder, Execute with optional mute filtering, and output rendering including filter hint.
Chat List Validation and Tests
shortcuts/im/im_chat_list_test.go
Tests for Cobra-backed runtime context, buildChatListParams defaults and overrides, page-size bounds validation, and DryRun endpoint/param inclusion.
Chat Search Enhancement for Mute Filtering
shortcuts/im/im_chat_search.go
Adds --exclude-muted flag, detects public_not_joined pre-skip, applies MaybeApplyMuteFilter to search results, conditionally adds filter metadata to output, and prints filter hints; updates comments.
Shortcut Dry-Run and Helper Tests
shortcuts/im/builders_test.go
DryRun tests verifying ImChatSearch (exclude-muted) and ImChatList request shapes; TestDetectAllNonMemberPreSkip coverage.
Shortcut Registration
shortcuts/im/shortcuts.go, shortcuts/im/helpers_test.go
Registers ImChatList in Shortcuts() and updates test ordering expectation.
Skills and Reference Documentation
skills/lark-im/SKILL.md, skills/lark-im/references/*
Adds +chat-list reference page, documents --exclude-muted workflow and filter metadata, updates chat-search docs and cross-references, and refreshes SKILL front-matter.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • YangJunzhou-01
  • liangshuo-1

Poem

🐰 A fluffy chat command hops into view,
Filtering mutes as the cool bunnies do,
I fetch IDs, drop whispers, keep the known,
Print hints and pages as the list is shown,
Hop, hop — your chats are clearer now!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: adding a new +chat-list shortcut and introducing the --exclude-muted flag to filter muted chats.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed PR description is comprehensive and well-structured, addressing all required template sections with detailed context.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added domain/im PR touches the im domain size/L Large or sensitive change across domains or core paths labels May 11, 2026
@shifengjuan-dev
shifengjuan-dev force-pushed the feat/im-chats-filter-muted branch 10 times, most recently from ae6dc21 to 04bacc1 Compare May 14, 2026 07:27
@github-actions

github-actions Bot commented May 14, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@3c89777b789aefa64895d0a9e90b1d78ed1f72f3

🧩 Skill update

npx skills add shifengjuan-dev/lark-cli#feat/im-chats-filter-muted -y -g

@shifengjuan-dev
shifengjuan-dev force-pushed the feat/im-chats-filter-muted branch from 04bacc1 to 3af634e Compare May 14, 2026 09:09
@codecov

codecov Bot commented May 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 61.94332% with 94 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.87%. Comparing base (5e0ac02) to head (3c89777).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/im/im_chat_list.go 25.00% 60 Missing ⚠️
shortcuts/im/im_chat_search.go 20.00% 20 Missing ⚠️
shortcuts/im/mute_filter.go 90.07% 14 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #820      +/-   ##
==========================================
- Coverage   65.90%   65.87%   -0.03%     
==========================================
  Files         518      520       +2     
  Lines       48834    49192     +358     
==========================================
+ Hits        32185    32407     +222     
- Misses      13882    14015     +133     
- Partials     2767     2770       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Change-Id: I22221ac5835667f58cbd40b34de75825d2445d1c
@shifengjuan-dev
shifengjuan-dev force-pushed the feat/im-chats-filter-muted branch from 3af634e to 3c89777 Compare May 14, 2026 09:32
@YangJunzhou-01
YangJunzhou-01 merged commit a54a879 into larksuite:main May 14, 2026
18 checks passed
@liangshuo-1 liangshuo-1 mentioned this pull request May 14, 2026
3 tasks
tuxedomm pushed a commit to zhumiaoxin/cli that referenced this pull request Jun 6, 2026
…ksuite#820)

Add im +chat-list shortcut wrapping GET /open-apis/im/v1/chats (previously not exposed via lark-cli).
Add --exclude-muted to both +chat-search and +chat-list: client-side filter that calls POST /open-apis/im/v1/chat_user_setting/batch_get_mute_status after each page and drops is_muted=true chats.
Introduce shortcuts/im/mute_filter.go with pure helpers and an orchestrator (MaybeApplyMuteFilter) shared by both shortcuts.

Change-Id: I22221ac5835667f58cbd40b34de75825d2445d1c
@coderabbitai coderabbitai Bot mentioned this pull request Jun 15, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/im PR touches the im domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants