Skip to content

feat: replace words for transcript#1372

Merged
zhangjun-bytedance merged 1 commit into
mainfrom
feat/transcript_word_replace0601
Jun 10, 2026
Merged

feat: replace words for transcript#1372
zhangjun-bytedance merged 1 commit into
mainfrom
feat/transcript_word_replace0601

Conversation

@zhangjun-bytedance

@zhangjun-bytedance zhangjun-bytedance commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Changes

  • Change 1
  • Change 2

Test Plan

  • Unit tests pass
  • Manual local verification confirms the lark-cli <domain> <command> flow works as expected

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Added minutes +summary, minutes +todo (single & batch) and minutes +word-replace commands with dry-run previews and structured success output.
  • Bug Fixes / Error Handling

    • Stronger input validation and clearer user-facing error mapping (e.g., no_edit_permission, words_not_found, others_are_editing).
  • Tests

    • Added extensive unit and e2e tests covering validation, dry-run, request payloads, batch behavior, and error paths.
  • Documentation

    • Updated minutes skill docs and added reference pages for summary, todo, and word-replace usage.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds three minutes CLI shortcuts—+summary (update summary), +todo (manage todos single/batch), and +word-replace (batch transcript word replacements)—with validation, DryRun/Execute HTTP flows, unit and e2e tests, and updated routing/docs.

Changes

Minutes Shortcuts: Summary, Todo, Word Replace

Layer / File(s) Summary
Summary shortcut implementation
shortcuts/minutes/minutes_summary.go
MinutesSummary validates required --minute-token and --summary, provides DryRun and Execute PUT to the minutes summary endpoint, and formats output with minute_token and updated: true.
Todo shortcut implementation
shortcuts/minutes/minutes_todo.go
MinutesTodo supports add/update/delete via single-item flags or batch --todos JSON, validates per-operation field rules, constructs todo_items payload, and remaps permission API errors into typed exit errors.
Word replace shortcut implementation
shortcuts/minutes/minutes_word_replace.go
MinutesWordReplace validates/parses --replace-words JSON array, runs DryRun/Execute PUT to transcript word endpoint, and remaps upstream errors (no_edit_permission, others_are_editing, words_not_found).
Unit tests: summary and todo
shortcuts/minutes/minutes_summary_todo_test.go
Covers DryRun output, validation failures, single-item and batch request bodies, incompatible flag combinations, permission-denied remapping, and help metadata.
Unit tests: word replace
shortcuts/minutes/minutes_word_replace_test.go
Covers flag validation, JSON parsing, DryRun output, successful execution response shape, and error-to-exit mapping for several upstream error scenarios.
Test token/constants tweaks
shortcuts/minutes/*_test.go
Replaces hard-coded minute tokens with shared constants in existing speaker/update tests and a missing-topic test.
E2E test: word replace
tests/cli_e2e/minutes/minutes_word_replace_test.go
End-to-end dry-run test asserting PUT method, target API path, and replacement word values in output.
Documentation and routing
skills/lark-minutes/SKILL.md, skills/lark-minutes/references/*, skills/lark-task/SKILL.md, skills/lark-vc/references/lark-vc-notes.md
Updates capability boundaries and routing: clarifies read (via vc +notes) vs write (via minutes +todo/+summary), adds reference pages for the new commands, and updates cross-skill disambiguation and notes about todo_id usage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • larksuite/cli#359: Overlaps at minutes shortcut registration and related shortcut changes.

Suggested labels

feature

Suggested reviewers

  • zhaoleibd

Poem

🐰 A rabbit typed and filed away,
Summaries, todos, words at play,
Tests snugly stitched and docs aligned,
Minute changes cleanly signed,
Hooray — the shortcuts save the day!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely incomplete, with the Summary section empty and the Changes section containing only placeholder text ('Change 1', 'Change 2') instead of describing the actual implementation details. Both test plan checkboxes remain unchecked. Fill the Summary with a 1-3 sentence overview of the feature scope. Replace 'Change 1' and 'Change 2' with actual changes: new shortcuts (MinutesSummary, MinutesTodo, MinutesWordReplace), tests, and documentation updates. Check or update the Test Plan section to reflect current verification status.
Docstring Coverage ⚠️ Warning Docstring coverage is 7.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: replace words for transcript' clearly and concisely describes the main feature addition: a word replacement capability for transcripts. It aligns with the primary changes across the shortcut implementations.
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/transcript_word_replace0601

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/task PR touches the task domain domain/vc PR touches the vc domain size/L Large or sensitive change across domains or core paths labels Jun 10, 2026
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.49817% with 86 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.95%. Comparing base (7fdf558) to head (4f22f44).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/minutes/minutes_todo.go 68.09% 28 Missing and 24 partials ⚠️
shortcuts/minutes/minutes_summary.go 32.14% 16 Missing and 3 partials ⚠️
shortcuts/minutes/minutes_word_replace.go 84.81% 6 Missing and 6 partials ⚠️
shortcuts/minutes/shortcuts.go 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1372      +/-   ##
==========================================
+ Coverage   71.90%   71.95%   +0.05%     
==========================================
  Files         691      699       +8     
  Lines       65629    66164     +535     
==========================================
+ Hits        47191    47611     +420     
- Misses      14791    14864      +73     
- Partials     3647     3689      +42     

☔ View full report in Codecov by Harness.
📢 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

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@4f22f4444c0c7e5ef39078a5bb83932fb936562e

🧩 Skill update

npx skills add larksuite/cli#feat/transcript_word_replace0601 -y -g

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

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

250-252: ⚖️ Poor tradeoff

Reconsider exposing todo_id constraint in output validation.

Line 250-252 asserts that the todo_id "must never be surfaced to the user in the command output". While hiding internal IDs is a reasonable UX decision, enforcing it via test assertions that scan stdout for the literal value "88" is fragile (e.g., it would break if a different field happened to contain "88", or if output formatting changes).

Consider whether this constraint belongs in the test suite or in code review/UX guidelines. If it must be tested, document the rationale clearly in a comment.

🤖 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_summary_todo_test.go` around lines 250 - 252, The
test currently asserts that stdout must not contain the literal "88" (using
stdout.String() and t.Errorf), which is fragile; update the test to either
remove this brittle literal-check or make it robust: parse the command output
(e.g., as JSON or structured fields) and assert that there is no "todo_id" key,
or change the assertion to check for the presence/absence of a labeled field
(like "todo_id") rather than the numeric value "88"; if you keep the constraint,
add a clear inline comment explaining why hiding the ID is required and
reference stdout/String() and the failing t.Errorf call so reviewers know this
is an intentional UX test.
🤖 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_summary_todo_test.go`:
- Around line 103-120: Update the test TestMinutesTodo_RequiresIsDone to assert
the typed validation error metadata instead of substring matching: when
mountAndRun (used in MinutesTodo tests) returns an error, assert the error is a
validation error created via errs.NewValidationError by using errs.ProblemOf to
check category/subtype/parameter (e.g., that ProblemOf(err) reports validation
and the parameter "is-done"), and also assert the original cause is preserved
via errs.Cause or similar helper; apply the same replacement pattern to
TestMinutesTodo_RequiresOperation and other validation error tests that
currently use strings.Contains on err.Error().

In `@shortcuts/minutes/minutes_summary.go`:
- Around line 36-49: The Validate function currently returns legacy
output.ErrValidation in three places (when minuteToken == "" , when
validate.ResourceName fails, and when summary == "" ); replace these with typed
validation errors using errs.NewValidationError(errs.SubtypeInvalidArgument,
"<message>") and attach the offending flag via .WithParam("--minute-token") or
.WithParam("--summary"); for the validate.ResourceName error wrap the returned
err into errs.NewValidationError(errs.SubtypeInvalidArgument,
err.Error()).WithParam("--minute-token") so command-facing failures are typed
correctly and include param metadata.

In `@shortcuts/minutes/minutes_todo.go`:
- Around line 65-77: In the Validate function replace legacy
output.ErrValidation calls with typed errs validation errors: when minuteToken
== "" return errs.NewValidationError(errs.SubtypeInvalidArgument, "missing
required flag").WithParam("--minute-token"); when
validate.ResourceName(minuteToken, "--minute-token") returns err wrap it as
errs.NewValidationError(errs.SubtypeInvalidArgument, "%s",
err).WithParam("--minute-token"); keep other logic (resolveMinuteTodoOps)
unchanged and ensure the returned error types are the new errs.* typed
validation errors so command-facing failures use the proper subtype and param
metadata.
- Around line 180-229: In resolveMinuteTodoSingle replace all uses of
output.ErrValidation with errs.NewValidationError(errs.SubtypeInvalidArgument,
"<message>").WithParam("<flag>") and return that error; specifically: the
missing operation case should use WithParam("--operation"); the "add" case
missing args should use WithParam("--todo") (and/or "--is-done" — prefer the
primary missing flag "--todo"); the "add" todo-id presence error should use
WithParam("--todo-id"); the "update" missing fields error should use
WithParam("--todo-id"); the "delete" missing todo-id error should use
WithParam("--todo-id"); the "delete" unexpected flags error should use
WithParam("--todo") (or "--is-done" as appropriate); and the default
unknown-operation error should use WithParam("--operation"); keep the rest of
resolveMinuteTodoSingle logic (minuteTodoSpec, buildMinuteTodoItem,
minuteTodoOp) unchanged. Replace the final build error return to wrap/convert
into a validation error similarly if it represents bad input.
- Around line 128-144: The file uses the legacy output.ErrValidation helper;
replace those calls with typed errs.NewValidationError calls: in
resolveMinuteTodoOps return errs.NewValidationError(errs.SubtypeInvalidArgument,
"use either --todos for batch or single-item flags (--operation, --todo,
--is-done, --todo-id), not both").WithParam("--todos") instead of
output.ErrValidation, and similarly replace the other output.ErrValidation
usages in this file (including those in
resolveMinuteTodoBatch/resolveMinuteTodoSingle flows) with
errs.NewValidationError(errs.SubtypeInvalidArgument, "<same validation
message>").WithParam("<relevant-flag>") using the specific flag name that caused
the validation (e.g., "--todos", "--operation", "--todo", "--is-done", or
"--todo-id") so each validation error is typed and carries the correct
parameter.

In `@shortcuts/minutes/minutes_word_replace.go`:
- Around line 48-60: The Validate function currently returns legacy
output.ErrValidation values; replace those with typed validation errors using
errs.NewValidationError(errs.SubtypeInvalidArgument,
"<message>").WithParam("--minute-token") for the minute-token checks and
errs.NewValidationError(errs.SubtypeInvalidArgument,
"<message>").WithParam("--replace-words") for the replace-words parse error;
update the three error returns in the Validate closure (the empty minuteToken
check, the validate.ResourceName(minuteToken, "--minute-token") error branch,
and the parseReplaceWords error branch) to construct and return the
corresponding errs.NewValidationError(...) instances preserving the original
messages and include the exact flag name via WithParam.

---

Nitpick comments:
In `@shortcuts/minutes/minutes_summary_todo_test.go`:
- Around line 250-252: The test currently asserts that stdout must not contain
the literal "88" (using stdout.String() and t.Errorf), which is fragile; update
the test to either remove this brittle literal-check or make it robust: parse
the command output (e.g., as JSON or structured fields) and assert that there is
no "todo_id" key, or change the assertion to check for the presence/absence of a
labeled field (like "todo_id") rather than the numeric value "88"; if you keep
the constraint, add a clear inline comment explaining why hiding the ID is
required and reference stdout/String() and the failing t.Errorf call so
reviewers know this is an intentional UX test.
🪄 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: 30f73c5f-9192-45aa-8139-65c585497c71

📥 Commits

Reviewing files that changed from the base of the PR and between 7fdf558 and 89aaeb7.

📒 Files selected for processing (12)
  • shortcuts/minutes/minutes_summary.go
  • shortcuts/minutes/minutes_summary_todo_test.go
  • shortcuts/minutes/minutes_todo.go
  • shortcuts/minutes/minutes_word_replace.go
  • shortcuts/minutes/minutes_word_replace_test.go
  • shortcuts/minutes/shortcuts.go
  • skills/lark-minutes/SKILL.md
  • skills/lark-minutes/references/lark-minutes-summary.md
  • skills/lark-minutes/references/lark-minutes-todo.md
  • skills/lark-task/SKILL.md
  • skills/lark-vc/references/lark-vc-notes.md
  • tests/cli_e2e/minutes/minutes_word_replace_test.go

Comment thread shortcuts/minutes/minutes_summary_todo_test.go
Comment thread shortcuts/minutes/minutes_summary.go
Comment thread shortcuts/minutes/minutes_todo.go
Comment thread shortcuts/minutes/minutes_todo.go
Comment thread shortcuts/minutes/minutes_todo.go
Comment thread shortcuts/minutes/minutes_word_replace.go
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
Comment thread shortcuts/minutes/minutes_summary_todo_test.go Outdated
@zhangjun-bytedance
zhangjun-bytedance force-pushed the feat/transcript_word_replace0601 branch from 071cd37 to 154f2fb Compare June 10, 2026 06:16
@zhangjun-bytedance
zhangjun-bytedance force-pushed the feat/transcript_word_replace0601 branch from 154f2fb to 4f22f44 Compare June 10, 2026 06:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (1)
shortcuts/minutes/minutes_word_replace.go (1)

116-126: 💤 Low value

Note: asymmetric trimming for source vs target words.

source_word is trimmed (line 116) but target_word is passed through without trimming (line 126). This asymmetry is intentional per the AI summary but could surprise users who accidentally include trailing whitespace in target_word. The current design prioritizes flexibility (allowing intentional whitespace in replacements) over defensive sanitization.

If you want stricter input handling, trim target_word as well:

Optional: trim target_word for consistency
 		seen[sourceWord] = struct{}{}
 		replaceWords = append(replaceWords, map[string]string{
 			"source_word": sourceWord,
-			"target_word": item.TargetWord,
+			"target_word": strings.TrimSpace(item.TargetWord),
 		})
🤖 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_word_replace.go` around lines 116 - 126, The code
trims source_word but leaves target_word untrimmed, causing inconsistent
handling; update the construction of replaceWords so that item.TargetWord is
trimmed (e.g., use strings.TrimSpace(item.TargetWord) when assigning
"target_word") and adjust any duplicate-detection or validation logic if it
relies on trimmed values (variables referenced: sourceWord, item.TargetWord,
seen, replaceWords, the map keys "source_word" and "target_word").
🤖 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/shortcuts.go`:
- Around line 15-16: Add end-to-end tests that exercise the MinutesSummary and
MinutesTodo shortcuts: create dry-run E2E cases in the tests/cli_e2e suite that
invoke the CLI with the "+summary" and "+todo" shortcuts and assert expected
outputs; if these shortcuts are newly added behavior, also add live E2E runs.
Locate the unit test references in
shortcuts/minutes/minutes_summary_todo_test.go and mirror those scenarios in new
E2E test files under tests/cli_e2e (calling the CLI binary and checking
stdout/stderr), ensuring the tests invoke the shortcuts by name (MinutesSummary,
MinutesTodo) and validate their outputs. Ensure tests are labeled as dry-run
(and add live variants only if appropriate) and follow existing E2E test
patterns for setup/teardown and assertions.

---

Nitpick comments:
In `@shortcuts/minutes/minutes_word_replace.go`:
- Around line 116-126: The code trims source_word but leaves target_word
untrimmed, causing inconsistent handling; update the construction of
replaceWords so that item.TargetWord is trimmed (e.g., use
strings.TrimSpace(item.TargetWord) when assigning "target_word") and adjust any
duplicate-detection or validation logic if it relies on trimmed values
(variables referenced: sourceWord, item.TargetWord, seen, replaceWords, the map
keys "source_word" and "target_word").
🪄 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: 842a6ed5-8170-4483-b955-087399ed6143

📥 Commits

Reviewing files that changed from the base of the PR and between 154f2fb and 4f22f44.

📒 Files selected for processing (14)
  • shortcuts/minutes/minutes_speaker_replace_test.go
  • shortcuts/minutes/minutes_summary.go
  • shortcuts/minutes/minutes_summary_todo_test.go
  • shortcuts/minutes/minutes_todo.go
  • shortcuts/minutes/minutes_update_test.go
  • shortcuts/minutes/minutes_word_replace.go
  • shortcuts/minutes/minutes_word_replace_test.go
  • shortcuts/minutes/shortcuts.go
  • skills/lark-minutes/SKILL.md
  • skills/lark-minutes/references/lark-minutes-summary.md
  • skills/lark-minutes/references/lark-minutes-todo.md
  • skills/lark-task/SKILL.md
  • skills/lark-vc/references/lark-vc-notes.md
  • tests/cli_e2e/minutes/minutes_word_replace_test.go
✅ Files skipped from review due to trivial changes (3)
  • skills/lark-vc/references/lark-vc-notes.md
  • shortcuts/minutes/minutes_update_test.go
  • shortcuts/minutes/minutes_speaker_replace_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/cli_e2e/minutes/minutes_word_replace_test.go
  • skills/lark-task/SKILL.md
  • shortcuts/minutes/minutes_todo.go
  • skills/lark-minutes/SKILL.md
  • shortcuts/minutes/minutes_summary.go

Comment thread shortcuts/minutes/shortcuts.go
@zhangjun-bytedance
zhangjun-bytedance merged commit 0d20a02 into main Jun 10, 2026
22 checks passed
@zhangjun-bytedance
zhangjun-bytedance deleted the feat/transcript_word_replace0601 branch June 10, 2026 06:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/task PR touches the task domain domain/vc PR touches the vc 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