Skip to content

feat(docs): support block mutation ranges - #2265

Open
ViperCai wants to merge 3 commits into
mainfrom
codex/block-replace-range
Open

feat(docs): support block mutation ranges#2265
ViperCai wants to merge 3 commits into
mainfrom
codex/block-replace-range

Conversation

@ViperCai

@ViperCai ViperCai commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Expose inclusive range selectors in docs +update for both block_replace and block_delete. The revision pinning/version behavior found during PPE testing is intentionally excluded and will be handled separately.

Changes

  • Add public start-block-id and end-block-id flags and pass them through verbatim as start_block_id and end_block_id.
  • Allow paired range selectors for block_replace and block_delete; reject incomplete pairs, block-id conflicts, unsupported commands, invalid sentinels, and delete content locally.
  • Document single-ID, comma-separated multi-ID, and same-parent continuous range usage.
  • Add unit and dry-run coverage for replace/delete payloads and validation.
  • Add a self-contained bot live E2E: create document, discover current block IDs, range replace, range delete, fetch verification, and cleanup.

Test Plan

  • Remote make unit-test passes.
  • Remote targeted docs shortcut tests pass.
  • Remote build plus docs dry-run range tests pass.
  • Remote go vet, formatting, go mod tidy diff check, and golangci-lint pass.
  • Skill format check passes.
  • Real PPE range behavior was re-verified after the gateway release; report: https://bytedance.larkoffice.com/docx/FrK1dgTPuo4VL2xRdyic4gLWnhe
  • GitHub e2e-live will run the new bot workflow with repository credentials after this push.

Related Issues

  • None

Dependencies

Summary by CodeRabbit

  • New Features

    • Added support for replacing or deleting an inclusive range of sibling blocks.
    • Added --start-block-id and --end-block-id options for defining operation ranges.
    • Added dry-run support for previewing ranged replacements and deletions.
  • Bug Fixes

    • Improved whitespace handling for block IDs.
    • Added validation for incomplete, conflicting, unsupported, or invalid range parameters.
    • Improved error details for invalid block mutation configurations.
  • Documentation

    • Added examples and guidance for single-block, multi-block, and consecutive-range operations.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The docs update command now supports inclusive multi-block block_replace and block_delete ranges through paired start and end block IDs. It validates range combinations, serializes them into update requests, documents the behavior, and adds unit and end-to-end coverage.

Changes

Inclusive block mutation ranges

Layer / File(s) Summary
Range flags and validation
shortcuts/doc/docs_update_v2.go
The v2 command adds paired range flags for block_replace and block_delete. It trims IDs and rejects incomplete, conflicting, unsupported, or invalid range combinations.
Request construction and test coverage
shortcuts/doc/docs_update_v2.go, shortcuts/doc/docs_update_test.go, shortcuts/doc/doc_errors_test.go, tests/cli_e2e/docs/*, tests/cli_e2e/docs/coverage.md
Update requests include range endpoints. Tests cover help text, valid payloads, validation errors, dry-run output, asynchronous replacement and deletion, block lookup, polling, and cleanup.
Reference documentation
skills/lark-doc/references/lark-doc-update.md
The reference documents format requirements, multi-block and inclusive range operations, constraints, examples, and the updated response fields.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant docs_update_v2
  participant DocumentsEndpoint
  participant DocumentFetch
  CLI->>docs_update_v2: submit ranged block_replace or block_delete
  docs_update_v2->>docs_update_v2: validate range endpoints
  docs_update_v2->>DocumentsEndpoint: send mutation request
  DocumentsEndpoint-->>CLI: return update result
  CLI->>DocumentFetch: fetch document content
  DocumentFetch-->>CLI: return updated content
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.79% 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 identifies support for block mutation ranges, which is the primary change in the pull request.
Description check ✅ Passed The description includes the required Summary, Changes, Test Plan, and Related Issues sections with relevant implementation and validation 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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/block-replace-range

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.

@github-actions github-actions Bot added domain/ccm PR touches the ccm domain size/M Single-domain feat or fix with limited business impact labels Aug 10, 2026
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.44%. Comparing base (2016120) to head (baec82b).
⚠️ Report is 28 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2265      +/-   ##
==========================================
+ Coverage   76.36%   76.44%   +0.08%     
==========================================
  Files        1011     1025      +14     
  Lines      111269   113732    +2463     
==========================================
+ Hits        84970    86945    +1975     
- Misses      19815    20113     +298     
- Partials     6484     6674     +190     

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

@ViperCai
ViperCai marked this pull request as ready for review August 10, 2026 09:48

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

🤖 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/doc/docs_update_v2.go`:
- Around line 76-79: Stop silently trimming block IDs: in
shortcuts/doc/docs_update_v2.go:76-79, preserve the supplied startBlockID and
endBlockID values or reject whitespace-padded IDs with the existing typed
validation pattern; in shortcuts/doc/docs_update_v2.go:276-280, serialize those
exact endpoint values without strings.TrimSpace; update
shortcuts/doc/docs_update_test.go:223-247 to verify exact preservation or typed
rejection instead of expecting trimmed values.

In `@tests/cli_e2e/docs/docs_update_dryrun_test.go`:
- Around line 102-119: Add a live bot-credential E2E test alongside the existing
block_replace coverage that creates a document containing three blocks, replaces
the inclusive range from li1 through li3, fetches the document, and asserts the
resulting block content. Make the test self-contained with document cleanup
using the existing test helpers and conventions.
🪄 Autofix

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 Plus

Run ID: e2165043-8667-4996-be8a-27ce9c7c65cb

📥 Commits

Reviewing files that changed from the base of the PR and between 2016120 and 1dfa37d.

📒 Files selected for processing (4)
  • shortcuts/doc/docs_update_test.go
  • shortcuts/doc/docs_update_v2.go
  • skills/lark-doc/references/lark-doc-update.md
  • tests/cli_e2e/docs/docs_update_dryrun_test.go

Comment thread shortcuts/doc/docs_update_v2.go Outdated
Comment on lines +102 to +119
{
name: "block_replace inclusive range",
args: []string{
"docs", "+update",
"--doc", "doxcnDryRunE2E",
"--command", "block_replace",
"--start-block-id", "li1",
"--end-block-id", "li3",
"--content", "<li>combined</li>",
"--dry-run",
},
wantContains: []string{"/open-apis/docs_ai/v1/documents/doxcnDryRunE2E"},
wantBody: map[string]any{
"command": "block_replace",
"start_block_id": "li1",
"end_block_id": "li3",
},
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Add live E2E coverage for inclusive range replacement.

This dry-run case verifies only request serialization. It does not verify that the service replaces every block from start_block_id through end_block_id.

Add a live bot-credential test that creates a document with three blocks, replaces the inclusive range, fetches the document, asserts the resulting block content, and cleans up the document.

As per coding guidelines, “New flows or behavior changes require live E2E coverage with a self-contained create/use/cleanup workflow and bot credentials where applicable.”

🤖 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 `@tests/cli_e2e/docs/docs_update_dryrun_test.go` around lines 102 - 119, Add a
live bot-credential E2E test alongside the existing block_replace coverage that
creates a document containing three blocks, replaces the inclusive range from
li1 through li3, fetches the document, and asserts the resulting block content.
Make the test self-contained with document cleanup using the existing test
helpers and conventions.

Source: Coding guidelines

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#codex/block-replace-range -y -g

@SunPeiYang996 SunPeiYang996 changed the title feat(docs): support block replace ranges feat(docs): support block mutation ranges Aug 12, 2026
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

PR Quality Summary

CI did not complete successfully. Use the failed check links below to decide whether this PR needs a code change or a rerun.

Failed checks

@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

🤖 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 `@tests/cli_e2e/docs/docs_update_test.go`:
- Around line 97-101: Add a distinct trailing fixture block after the final
entry in the deletion range used by the test, then assert after the delete
operation that this trailing block still exists. Update the nearby assertions in
the test’s deletion flow so the regression specifically verifies blocks after
end-block-id are preserved.
🪄 Autofix

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 Plus

Run ID: 7ead8433-1e6f-42bc-9645-16944dbb1e93

📥 Commits

Reviewing files that changed from the base of the PR and between 84bde46 and baec82b.

📒 Files selected for processing (7)
  • shortcuts/doc/doc_errors_test.go
  • shortcuts/doc/docs_update_test.go
  • shortcuts/doc/docs_update_v2.go
  • skills/lark-doc/references/lark-doc-update.md
  • tests/cli_e2e/docs/coverage.md
  • tests/cli_e2e/docs/docs_update_dryrun_test.go
  • tests/cli_e2e/docs/docs_update_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • shortcuts/doc/docs_update_test.go
  • skills/lark-doc/references/lark-doc-update.md
  • shortcuts/doc/docs_update_v2.go

Comment on lines +97 to +101
deleteTargets := []string{
"range-delete-a-" + suffix,
"range-delete-b-" + suffix,
"range-delete-c-" + suffix,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add a block after the deletion range.

The deletion range ends at the final fixture block. A delete operation that removes one or more blocks after --end-block-id will pass this test.

Add a distinct trailing block. Assert that it remains after deletion.

Proposed test change
  deleteTargets := []string{
    "range-delete-a-" + suffix,
    "range-delete-b-" + suffix,
    "range-delete-c-" + suffix,
  }
+ deleteTail := "range-delete-tail-" + suffix
  replacement := "range-replaced-" + suffix

  folderToken := drive.CreateDriveFolder(t, parentT, ctx, "lark-cli-e2e-range-folder-"+suffix, defaultAs, "")
  docToken := createDocWithRetry(t, parentT, ctx, folderToken, "lark-cli-e2e-range-"+suffix,
-   strings.Join(append(append([]string{}, replaceTargets...), deleteTargets...), "\n\n"), defaultAs)
+   strings.Join(append(append(append([]string{}, replaceTargets...), deleteTargets...), deleteTail), "\n\n"), defaultAs)

  // ...
- return strings.Contains(afterDelete, replacement) && !containsAny(afterDelete, deleteTargets), nil
+ return strings.Contains(afterDelete, replacement) &&
+   strings.Contains(afterDelete, deleteTail) &&
+   !containsAny(afterDelete, deleteTargets), nil

As per coding guidelines, “Every behavior change requires a nearby regression test that fails when the implementation is reverted; tests should assert fields, requests, typed errors, or side effects directly.”

Also applies to: 161-169

🤖 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 `@tests/cli_e2e/docs/docs_update_test.go` around lines 97 - 101, Add a distinct
trailing fixture block after the final entry in the deletion range used by the
test, then assert after the delete operation that this trailing block still
exists. Update the nearby assertions in the test’s deletion flow so the
regression specifically verifies blocks after end-block-id are preserved.

Source: Coding guidelines

@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 all sign our Contributor License Agreement before we can accept your contribution.
0 out of 2 committers have signed the CLA.

❌ ViperCai
❌ SunPeiYang996
You have signed the CLA already but the status is still pending? Let us recheck it.

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/M Single-domain feat or fix with limited business impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants