Skip to content

feat(minutes): add minutes edit shortcuts#1036

Open
calendar-assistant wants to merge 1 commit into
mainfrom
feat/minutes-shortcut
Open

feat(minutes): add minutes edit shortcuts#1036
calendar-assistant wants to merge 1 commit into
mainfrom
feat/minutes-shortcut

Conversation

@calendar-assistant
Copy link
Copy Markdown
Collaborator

@calendar-assistant calendar-assistant commented May 22, 2026

Summary

Adds minutes editing shortcuts so agents can update minute titles and replace transcript speakers from the CLI with structured validation and actionable API error hints.

Changes

  • Add minutes +update for updating a minute title through the minutes update API.
  • Add minutes +speaker-replace for rebinding transcript speakers between user open IDs.
  • Register both shortcuts, document them in the lark-minutes skill, and add unit plus dry-run E2E coverage.

Test Plan

  • make unit-test
  • go vet ./...
  • gofmt -l . produced no output
  • go mod tidy left the worktree clean
  • go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 run --new-from-rev=origin/main
  • go test ./tests/cli_e2e/minutes

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Added minutes +update to rename minutes (update topic).
    • Added minutes +speaker-replace to reassign utterances from one speaker to another.
  • Bug Fixes / UX

    • Improved validation and clearer error messages for required flags and permission issues.
    • Dry-run now shows the HTTP request payload for previewing changes.
  • Documentation

    • Added reference pages and updated skill docs with usage, examples, and required scopes.
  • Tests

    • Added unit and end-to-end tests covering validation, dry-run, execution, and error handling.

Review Change Stack

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label May 22, 2026
result, err := clie2e.RunCmd(ctx, clie2e.Request{
Args: []string{
"minutes", "+speaker-replace",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:tests/cli_e2e/minutes/minutes_speaker_replace_test.go:generic-api-key:25 >> .gitleaksignore


err := mountAndRun(t, MinutesUpdate, []string{
"+update",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_update_test.go:generic-api-key:61 >> .gitleaksignore


err := mountAndRun(t, MinutesUpdate, []string{
"+update",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_update_test.go:generic-api-key:97 >> .gitleaksignore


err := mountAndRun(t, MinutesUpdate, []string{
"+update",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_update_test.go:generic-api-key:121 >> .gitleaksignore

result, err := clie2e.RunCmd(ctx, clie2e.Request{
Args: []string{
"minutes", "+update",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:tests/cli_e2e/minutes/minutes_update_test.go:generic-api-key:25 >> .gitleaksignore


err := mountAndRun(t, MinutesSpeakerReplace, []string{
"+speaker-replace",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_speaker_replace_test.go:generic-api-key:81 >> .gitleaksignore


err := mountAndRun(t, MinutesSpeakerReplace, []string{
"+speaker-replace",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_speaker_replace_test.go:generic-api-key:121 >> .gitleaksignore


err := mountAndRun(t, MinutesSpeakerReplace, []string{
"+speaker-replace",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_speaker_replace_test.go:generic-api-key:146 >> .gitleaksignore


err := mountAndRun(t, MinutesSpeakerReplace, []string{
"+speaker-replace",
"--minute-token", "obcnq3b9jl72l83w4f149w9c",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 323fc7f.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 323fc7f35b395ac908209e955af2804cd3334c50:shortcuts/minutes/minutes_speaker_replace_test.go:generic-api-key:191 >> .gitleaksignore

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3eeefe7f-c7ea-4262-9477-11dce3176af6

📥 Commits

Reviewing files that changed from the base of the PR and between 323fc7f and 201fc1e.

📒 Files selected for processing (10)
  • shortcuts/minutes/minutes_speaker_replace.go
  • shortcuts/minutes/minutes_speaker_replace_test.go
  • shortcuts/minutes/minutes_update.go
  • shortcuts/minutes/minutes_update_test.go
  • shortcuts/minutes/shortcuts.go
  • skills/lark-minutes/SKILL.md
  • skills/lark-minutes/references/lark-minutes-speaker-replace.md
  • skills/lark-minutes/references/lark-minutes-update.md
  • tests/cli_e2e/minutes/minutes_speaker_replace_test.go
  • tests/cli_e2e/minutes/minutes_update_test.go

📝 Walkthrough

Walkthrough

This PR introduces two new minutes shortcuts to the Lark CLI: minutes +update renames minute titles via PATCH, and minutes +speaker-replace reassigns speakers in transcripts via PUT. Both include flag validation, dry-run support, structured error handling, comprehensive unit and e2e tests, and user documentation with reference guides.

Changes

Minutes Shortcuts

Layer / File(s) Summary
Minutes +update shortcut implementation
shortcuts/minutes/minutes_update.go
Defines MinutesUpdate shortcut with validation for --minute-token and --topic, dry-run PATCH request preparation, API execution, and error handler that wraps permission errors into structured exit errors with user-facing messages.
Minutes +update testing
shortcuts/minutes/minutes_update_test.go, tests/cli_e2e/minutes/minutes_update_test.go
Unit tests validate required flags, verify dry-run output includes PATCH method and endpoint, confirm successful API execution, and assert permission error handling with structured details. E2E test runs the command in dry-run mode and validates request output format.
Minutes +speaker-replace shortcut implementation
shortcuts/minutes/minutes_speaker_replace.go
Defines MinutesSpeakerReplace shortcut with validation for --minute-token, --from-user-id, and --to-user-id (including format and inequality checks), dry-run PUT request preparation, API execution, and error handler mapping specific API codes to structured exit errors for permission and speaker-not-found scenarios.
Minutes +speaker-replace testing
shortcuts/minutes/minutes_speaker_replace_test.go, tests/cli_e2e/minutes/minutes_speaker_replace_test.go
Unit tests validate flag constraints, verify dry-run output with PUT method and endpoint, confirm successful execution, and test speaker-not-found and no-edit-permission error cases with structured error details. E2E test validates dry-run mode execution and request output.
Shortcut registry and documentation
shortcuts/minutes/shortcuts.go, skills/lark-minutes/SKILL.md, skills/lark-minutes/references/lark-minutes-update.md, skills/lark-minutes/references/lark-minutes-speaker-replace.md
Registers both shortcuts in the registry. Updates skill documentation (removes local-command warning), adds routing rules and shortcut entries, and provides reference pages with usage examples, parameter descriptions, required OAuth scopes, and output field mappings.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • larksuite/cli#101: Both PRs touch the minutes shortcut registration plumbing—shortcuts/minutes/shortcuts.go—by adding different subcommands to the same exported minutes.Shortcuts() slice.

Suggested labels

domain/vc, size/M

Suggested reviewers

  • zhaoleibd

Poem

🐰 A tiny hop, a clever tweak,
Update titles, swap a speaker's streak.
With tests that run and docs that sing,
The minutes CLI now has new spring. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% 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 describes the main change: adding minutes edit shortcuts, which aligns with the core functionality introduced across multiple files.
Description check ✅ Passed The description follows the template structure with Summary, Changes, Test Plan, and Related Issues sections, all properly filled out with relevant details.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/minutes-shortcut

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

❌ Patch coverage is 83.06452% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.79%. Comparing base (ffcf778) to head (201fc1e).

Files with missing lines Patch % Lines
shortcuts/minutes/minutes_speaker_replace.go 85.89% 6 Missing and 5 partials ⚠️
shortcuts/minutes/minutes_update.go 81.81% 4 Missing and 4 partials ⚠️
shortcuts/minutes/shortcuts.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1036      +/-   ##
==========================================
+ Coverage   67.75%   67.79%   +0.04%     
==========================================
  Files         590      592       +2     
  Lines       55188    55312     +124     
==========================================
+ Hits        37392    37501     +109     
- Misses      14684    14691       +7     
- Partials     3112     3120       +8     

☔ 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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 22, 2026

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@201fc1eb8ac753558f0236f2ed7f58c5e85a1113

🧩 Skill update

npx skills add larksuite/cli#feat/minutes-shortcut -y -g

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: 2

🧹 Nitpick comments (1)
shortcuts/minutes/minutes_speaker_replace_test.go (1)

105-129: ⚡ Quick win

Strengthen execute-path assertions for output contract.

Line 126-Line 129 currently verifies only success status. Add assertions for minute_token, from_user_id, and to_user_id in formatted output to catch response-format regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/minutes/minutes_speaker_replace_test.go` around lines 105 - 129, In
TestMinutesSpeakerReplace_Execute enhance the success-path assertions by parsing
the command output (stdout) produced by mountAndRun when running
MinutesSpeakerReplace and asserting the formatted JSON includes the expected
fields: minute_token (should equal "obcnq3b9jl72l83w4f149w9c"), from_user_id
(should equal "ou_old_speaker"), and to_user_id (should equal "ou_new_speaker");
update the test to unmarshal stdout into a struct/map and add checks for these
keys alongside the existing success check to catch response-format regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shortcuts/minutes/minutes_speaker_replace_test.go`:
- Around line 18-19: Add explicit config-dir isolation to the unit tests by
calling t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) at the start of each
test (e.g., inside TestMinutesSpeakerReplace_Validate and the other test
functions in this file) or by invoking a shared helper before calling
cmdutil.TestFactory; ensure the environment variable is set before any config is
loaded so tests do not share config state across runs.

In `@shortcuts/minutes/minutes_update_test.go`:
- Around line 18-20: Several unit tests (including TestMinutesUpdate_Validate
and the other test functions that call cmdutil.TestFactory within this file)
share global CLI config state; add isolation by calling
t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) at the start of each test that
invokes cmdutil.TestFactory (i.e., before f, _, _, _ :=
cmdutil.TestFactory(...)). This ensures each test uses its own temporary config
directory and prevents cross-test state leakage.

---

Nitpick comments:
In `@shortcuts/minutes/minutes_speaker_replace_test.go`:
- Around line 105-129: In TestMinutesSpeakerReplace_Execute enhance the
success-path assertions by parsing the command output (stdout) produced by
mountAndRun when running MinutesSpeakerReplace and asserting the formatted JSON
includes the expected fields: minute_token (should equal
"obcnq3b9jl72l83w4f149w9c"), from_user_id (should equal "ou_old_speaker"), and
to_user_id (should equal "ou_new_speaker"); update the test to unmarshal stdout
into a struct/map and add checks for these keys alongside the existing success
check to catch response-format regressions.
🪄 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: 409325d5-606f-4978-95a7-5d4aea9a1a08

📥 Commits

Reviewing files that changed from the base of the PR and between ffcf778 and 323fc7f.

📒 Files selected for processing (10)
  • shortcuts/minutes/minutes_speaker_replace.go
  • shortcuts/minutes/minutes_speaker_replace_test.go
  • shortcuts/minutes/minutes_update.go
  • shortcuts/minutes/minutes_update_test.go
  • shortcuts/minutes/shortcuts.go
  • skills/lark-minutes/SKILL.md
  • skills/lark-minutes/references/lark-minutes-speaker-replace.md
  • skills/lark-minutes/references/lark-minutes-update.md
  • tests/cli_e2e/minutes/minutes_speaker_replace_test.go
  • tests/cli_e2e/minutes/minutes_update_test.go

Comment thread shortcuts/minutes/minutes_speaker_replace_test.go
Comment thread shortcuts/minutes/minutes_update_test.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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