Skip to content

feat(sheets): add cell operation shortcuts for merge, replace, and style#412

Open
caojie0621 wants to merge 1 commit intomainfrom
feat/sheet_cell
Open

feat(sheets): add cell operation shortcuts for merge, replace, and style#412
caojie0621 wants to merge 1 commit intomainfrom
feat/sheet_cell

Conversation

@caojie0621
Copy link
Copy Markdown
Collaborator

@caojie0621 caojie0621 commented Apr 11, 2026

Summary

Add 5 new sheets shortcuts for cell operations: merge/unmerge cells, find-and-replace, set style, and batch set style.

Changes

  • +merge-cells: merge cells with MERGE_ALL/MERGE_ROWS/MERGE_COLUMNS
  • +unmerge-cells: split merged cells
  • +replace: find and replace cell values with regex/case-sensitive options
  • +set-style: set cell style (font, color, alignment, border)
  • +batch-set-style: batch set styles for multiple ranges
  • Unit tests for all 5 shortcuts (30 cases, 81-89% coverage)
  • Skill reference docs for all 5 shortcuts

Test Plan

  • Unit tests pass (go test ./shortcuts/sheets/)
  • Manual local verification confirms all 5 lark-cli sheets +xxx commands work as expected

Related Issues

  • None

Summary by CodeRabbit

  • New Features

    • Added merge/unmerge, find-and-replace, set-style, and batch-set-style spreadsheet commands with CLI flags and a dry-run preview mode.
  • Documentation

    • Added reference guides for each new command with examples, parameters, and output descriptions.
  • Tests

    • Added comprehensive tests covering validation, dry-run output, execution paths, and error handling.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2026

📝 Walkthrough

Walkthrough

Adds five new Sheets shortcuts—+merge-cells, +unmerge-cells, +replace, +set-style, and +batch-set-style—with implementations, validation, dry-run and execute paths, tests, and user documentation. Each shortcut derives spreadsheet token from --spreadsheet-token or --url and calls the Sheets API endpoints.

Changes

Cohort / File(s) Summary
Sheet Cell Operations - Implementation
shortcuts/sheets/sheet_merge_cells.go, shortcuts/sheets/sheet_unmerge_cells.go, shortcuts/sheets/sheet_replace.go, shortcuts/sheets/sheet_set_style.go, shortcuts/sheets/sheet_batch_set_style.go
Added five new shortcuts implementing merge, unmerge, replace, set-style, and batch-set-style. Each includes flag declarations, token derivation from --url/--spreadsheet-token, input validation, DryRun request templating (POST/PUT), and Execute using path-encoded token with runtime.CallAPI and output to runtime.Out.
Sheet Cell Operations - Tests
shortcuts/sheets/sheet_cell_ops_test.go
Comprehensive tests for the five commands: validation (missing token/flags, JSON parsing/type checks), DryRun assertions (endpoint id, HTTP method, payload fields, normalized ranges), and Execute tests using HTTP stubs (request body checks, success/error handling, stdout validation).
Shortcuts Registry
shortcuts/sheets/shortcuts.go
Registered the five new shortcuts in Shortcuts() slice.
User Documentation
skills/lark-sheets/SKILL.md, skills/lark-sheets/references/lark-sheets-{merge-cells,unmerge-cells,replace,set-style,batch-set-style}.md
Added documentation and reference pages for each new shortcut with examples, parameter tables, dry-run guidance, and expected JSON outputs.

Sequence Diagram(s)

sequenceDiagram
    participant User as CLI User
    participant CLI as CLI Handler
    participant Validator as Validator
    participant Executor as Executor
    participant API as Sheets API
    participant Output as Output Handler

    User->>CLI: Invoke sheets +<operation>\n(--url/--spreadsheet-token, flags)
    CLI->>Validator: Validate flags
    Validator->>Validator: Derive spreadsheet token\n(from --spreadsheet-token or --url)
    Validator->>Validator: Validate operation-specific inputs
    Validator-->>CLI: Return validation result

    alt DryRun
        CLI->>Executor: Build DryRun request
        Executor->>Executor: Normalize ranges / parse JSON
        Executor-->>CLI: Return request preview
        CLI-->>User: Display request preview
    else Execute
        CLI->>Executor: Execute operation
        Executor->>Executor: Prepare payload / path-encode token
        Executor->>API: POST/PUT /open-apis/sheets/...
        API-->>Executor: Return response
        Executor->>Output: Write result to runtime.Out
        Output-->>User: Print JSON output
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • fangshuyu-768
  • zgz2048

Poem

🐰 New shortcuts hop in, nimble and spry,
Merge, split, replace, style—cells catch my eye.
Tests all green and docs neatly penned,
Batch styles aplenty, updates to send.
hops away with a carrot and a CLI grin

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.22% 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 summarizes the main addition of five new cell operation shortcuts (merge, unmerge, replace, set-style, batch-set-style) for the sheets service.
Description check ✅ Passed The PR description follows the template structure with all required sections completed: Summary, Changes, Test Plan, and Related Issues. It provides specific details about the five new shortcuts, test coverage, and verification approach.

✏️ 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/sheet_cell

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

@github-actions github-actions bot added domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths labels Apr 11, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 11, 2026

Greptile Summary

This PR adds 5 new sheets shortcuts — +merge-cells, +unmerge-cells, +replace, +set-style, and +batch-set-style — each wiring the corresponding Lark Sheets v2/v3 API endpoints, with 30 test cases and reference documentation. The implementation follows existing patterns well and the previously flagged json.Unmarshal error-handling gaps in Execute are correctly addressed (errors are returned rather than silently dropped).

Confidence Score: 5/5

Safe to merge — all previously raised concerns are addressed and the single new observation is low-risk

All five shortcuts follow established patterns, errors are properly propagated in Execute, tests cover 30 cases including validation/dry-run/success/error paths, and documentation is updated. The one new comment about the bare sheet-ID default for find_condition.range is P2 — it may be intentional and the author manually verified the commands work end-to-end.

shortcuts/sheets/sheet_replace.go — the find_condition.range default behavior when --range is omitted

Important Files Changed

Filename Overview
shortcuts/sheets/sheet_replace.go Adds +replace shortcut with find/replace logic; has a question around bare sheet ID used as find_condition.range default when --range is omitted
shortcuts/sheets/sheet_merge_cells.go Clean +merge-cells implementation using POST v2 merge_cells endpoint with proper range normalization and token handling
shortcuts/sheets/sheet_unmerge_cells.go Clean +unmerge-cells implementation mirroring merge-cells, no issues found
shortcuts/sheets/sheet_set_style.go +set-style using PUT v2 style endpoint; Execute properly returns json.Unmarshal errors (DryRun silently ignores — previously flagged)
shortcuts/sheets/sheet_batch_set_style.go +batch-set-style using PUT v2 styles_batch_update; Execute properly returns json.Unmarshal errors (DryRun silently ignores — previously flagged)
shortcuts/sheets/sheet_cell_ops_test.go Comprehensive 30-case test suite covering validate, dry-run, execute-success, and execute-error for all 5 new shortcuts
shortcuts/sheets/shortcuts.go All 5 new shortcuts correctly registered in the Shortcuts() slice

Sequence Diagram

sequenceDiagram
    participant CLI as lark-cli sheets
    participant Validate
    participant DryRun
    participant Execute
    participant LarkAPI as Lark Sheets API

    CLI->>Validate: token, range, flags
    Validate-->>CLI: error | nil

    alt --dry-run flag
        CLI->>DryRun: token, range, flags
        DryRun-->>CLI: DryRunAPI (method, url, body preview)
    else execute
        CLI->>Execute: token, range, flags
        Execute->>LarkAPI: POST/PUT /open-apis/sheets/v2|v3/...
        Note over Execute,LarkAPI: merge_cells / unmerge_cells (v2) style / styles_batch_update (v2) sheets/{id}/replace (v3)
        LarkAPI-->>Execute: JSON response
        Execute-->>CLI: runtime.Out(result)
    end
Loading

Reviews (2): Last reviewed commit: "feat(sheets): add cell operation shortcu..." | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 11, 2026

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/sheet_cell -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

🤖 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/sheets/sheet_replace.go`:
- Around line 41-43: validateSheetRangeInput currently lets absolute ranges like
"sheet2!A1:B2" bypass validation, so calling SheetReplace with --sheet-id sheet1
and --range sheet2!A1:B2 produces a contradictory request; update
validateSheetRangeInput to parse the range for an explicit sheet name and, if
present, ensure it matches the provided sheet-id (rejecting with an error on
mismatch), or change the function signature used by the three call sites (the
validateSheetRangeInput calls in SheetReplace flow) to accept both sheet-id and
range and perform this check; add a regression test that calls the SheetReplace
entrypoint with conflicting --sheet-id and absolute --range and asserts it
returns an error.

In `@shortcuts/sheets/sheet_set_style.go`:
- Around line 37-40: The current unmarshalling into a plain interface{} allows
arrays, strings, and null for runtime.Str("style"); change the validation so
that after json.Unmarshal you assert the result is an object
(map[string]interface{} or map[string]any) and return a FlagErrorf if it's not;
specifically update the block around variable style, the json.Unmarshal call,
and the place that assigns to appendStyle.style to only accept an object-shaped
map and reject other JSON types with an error like "--style must be a JSON
object".
🪄 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: 74ad2f72-1fe0-4362-84ca-7fe86f9a0343

📥 Commits

Reviewing files that changed from the base of the PR and between a00dfad and 8961893.

📒 Files selected for processing (13)
  • shortcuts/sheets/sheet_batch_set_style.go
  • shortcuts/sheets/sheet_cell_ops_test.go
  • shortcuts/sheets/sheet_merge_cells.go
  • shortcuts/sheets/sheet_replace.go
  • shortcuts/sheets/sheet_set_style.go
  • shortcuts/sheets/sheet_unmerge_cells.go
  • shortcuts/sheets/shortcuts.go
  • skills/lark-sheets/SKILL.md
  • skills/lark-sheets/references/lark-sheets-batch-set-style.md
  • skills/lark-sheets/references/lark-sheets-merge-cells.md
  • skills/lark-sheets/references/lark-sheets-replace.md
  • skills/lark-sheets/references/lark-sheets-set-style.md
  • skills/lark-sheets/references/lark-sheets-unmerge-cells.md

Add 5 new sheet shortcuts for cell operations:
- +merge-cells: merge cells with MERGE_ALL/MERGE_ROWS/MERGE_COLUMNS
- +unmerge-cells: split merged cells
- +replace: find and replace cell values
- +set-style: set cell style (font, color, alignment, border)
- +batch-set-style: batch set styles for multiple ranges

Includes unit tests (81-89% coverage) and skill reference docs.
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)
shortcuts/sheets/sheet_unmerge_cells.go (1)

28-31: Consider centralizing spreadsheet token resolution to avoid drift.

The same --url/--spreadsheet-token resolution logic is duplicated in Validate, DryRun, and Execute. A small helper (e.g., resolveSpreadsheetToken(runtime)) would reduce maintenance risk.

Refactor sketch
+func resolveSpreadsheetToken(runtime *common.RuntimeContext) string {
+	token := runtime.Str("spreadsheet-token")
+	if runtime.Str("url") != "" {
+		token = extractSpreadsheetToken(runtime.Str("url"))
+	}
+	return token
+}
...
- token := runtime.Str("spreadsheet-token")
- if runtime.Str("url") != "" {
-   token = extractSpreadsheetToken(runtime.Str("url"))
- }
+ token := resolveSpreadsheetToken(runtime)

Also applies to: 41-44, 54-57

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

In `@shortcuts/sheets/sheet_unmerge_cells.go` around lines 28 - 31, The
spreadsheet token resolution logic (using runtime.Str("spreadsheet-token") and
overriding with extractSpreadsheetToken(runtime.Str("url"))) is duplicated
across Validate, DryRun, and Execute; create a small helper function (e.g.,
resolveSpreadsheetToken(runtime) or resolveSpreadsheetTokenFromRuntime) that
accepts the runtime object, encapsulates the token selection logic and
extractSpreadsheetToken call, and replace the duplicated blocks in Validate,
DryRun, and Execute with calls to this helper to centralize behavior and avoid
drift.
shortcuts/sheets/sheet_set_style.go (1)

75-77: Keep Execute style-type checks consistent with Validate.

Validate enforces object-only JSON, but Execute currently re-parses without re-checking the object type. Consider using one shared parser/validator to keep behavior consistent and prevent future drift.

Refactor sketch
+func parseStyleObject(raw string) (map[string]interface{}, error) {
+	var style map[string]interface{}
+	if err := json.Unmarshal([]byte(raw), &style); err != nil {
+		return nil, common.FlagErrorf("--style must be valid JSON: %v", err)
+	}
+	if style == nil {
+		return nil, common.FlagErrorf("--style must be a JSON object")
+	}
+	return style, nil
+}
...
- var style interface{}
- if err := json.Unmarshal([]byte(runtime.Str("style")), &style); err != nil {
-   return common.FlagErrorf("--style must be valid JSON: %v", err)
- }
+ style, err := parseStyleObject(runtime.Str("style"))
+ if err != nil {
+   return err
+ }
Based on learnings: “In the `larksuite/cli` shortcut runner, `Validate` is always executed before `DryRun` … guards are intentionally kept in `Validate` and not duplicated in `DryRun`.”

Also applies to: 83-86

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

In `@shortcuts/sheets/sheet_set_style.go` around lines 75 - 77, Execute currently
unmarshals runtime.Str("style") with json.Unmarshal into style without
re-checking that the JSON is an object like Validate enforces; update Execute
(in sheet_set_style.go, the Execute method that calls
json.Unmarshal([]byte(runtime.Str("style")), &style)) to reuse the same
parsing/validation logic used by Validate (or call a shared helper) so the
parsed value is verified to be a JSON object (map[string]interface{}) before
proceeding and return a FlagError if it is not; ensure the helper accepts the
raw string (runtime.Str("style")), returns the parsed object, and is used by
both Validate and Execute to keep behavior consistent.
🤖 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/sheets/sheet_set_style.go`:
- Around line 75-77: Execute currently unmarshals runtime.Str("style") with
json.Unmarshal into style without re-checking that the JSON is an object like
Validate enforces; update Execute (in sheet_set_style.go, the Execute method
that calls json.Unmarshal([]byte(runtime.Str("style")), &style)) to reuse the
same parsing/validation logic used by Validate (or call a shared helper) so the
parsed value is verified to be a JSON object (map[string]interface{}) before
proceeding and return a FlagError if it is not; ensure the helper accepts the
raw string (runtime.Str("style")), returns the parsed object, and is used by
both Validate and Execute to keep behavior consistent.

In `@shortcuts/sheets/sheet_unmerge_cells.go`:
- Around line 28-31: The spreadsheet token resolution logic (using
runtime.Str("spreadsheet-token") and overriding with
extractSpreadsheetToken(runtime.Str("url"))) is duplicated across Validate,
DryRun, and Execute; create a small helper function (e.g.,
resolveSpreadsheetToken(runtime) or resolveSpreadsheetTokenFromRuntime) that
accepts the runtime object, encapsulates the token selection logic and
extractSpreadsheetToken call, and replace the duplicated blocks in Validate,
DryRun, and Execute with calls to this helper to centralize behavior and avoid
drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc1b952d-7b47-41b3-baec-313caf16957e

📥 Commits

Reviewing files that changed from the base of the PR and between 8961893 and e9456db.

📒 Files selected for processing (13)
  • shortcuts/sheets/sheet_batch_set_style.go
  • shortcuts/sheets/sheet_cell_ops_test.go
  • shortcuts/sheets/sheet_merge_cells.go
  • shortcuts/sheets/sheet_replace.go
  • shortcuts/sheets/sheet_set_style.go
  • shortcuts/sheets/sheet_unmerge_cells.go
  • shortcuts/sheets/shortcuts.go
  • skills/lark-sheets/SKILL.md
  • skills/lark-sheets/references/lark-sheets-batch-set-style.md
  • skills/lark-sheets/references/lark-sheets-merge-cells.md
  • skills/lark-sheets/references/lark-sheets-replace.md
  • skills/lark-sheets/references/lark-sheets-set-style.md
  • skills/lark-sheets/references/lark-sheets-unmerge-cells.md
✅ Files skipped from review due to trivial changes (7)
  • shortcuts/sheets/shortcuts.go
  • skills/lark-sheets/SKILL.md
  • skills/lark-sheets/references/lark-sheets-replace.md
  • skills/lark-sheets/references/lark-sheets-merge-cells.md
  • skills/lark-sheets/references/lark-sheets-batch-set-style.md
  • skills/lark-sheets/references/lark-sheets-unmerge-cells.md
  • skills/lark-sheets/references/lark-sheets-set-style.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • shortcuts/sheets/sheet_batch_set_style.go
  • shortcuts/sheets/sheet_merge_cells.go
  • shortcuts/sheets/sheet_cell_ops_test.go
  • shortcuts/sheets/sheet_replace.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/ccm PR touches the ccm 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.

1 participant