Skip to content

feat(doc): warn before overwrite when document contains whiteboard or file blocks#825

Open
herbertliu wants to merge 3 commits into
mainfrom
feat/docs-overwrite-resource-block-guard
Open

feat(doc): warn before overwrite when document contains whiteboard or file blocks#825
herbertliu wants to merge 3 commits into
mainfrom
feat/docs-overwrite-resource-block-guard

Conversation

@herbertliu
Copy link
Copy Markdown
Collaborator

@herbertliu herbertliu commented May 11, 2026

Summary

Add a best-effort pre-flight guard for the v1 overwrite mode that warns the user when the current document contains whiteboard or file attachment blocks that cannot be reconstructed from Markdown.

Changes

  • shortcuts/doc/docs_update.go: In executeUpdateV1, pre-fetch the document when --mode overwrite and call warnOverwriteResourceBlocks / checkOverwriteResourceBlocks to detect resource blocks
  • shortcuts/doc/docs_update_test.go: Add TestCheckOverwriteResourceBlocks with table-driven cases covering single/multiple whiteboard blocks, file attachments, and combined cases

Behaviour

When --mode overwrite is used and the current document contains <whiteboard> or <file> blocks:

warning: the document contains 2 whiteboard blocks and 1 file attachment block that cannot be
reconstructed from Markdown; overwrite will permanently delete them.
Consider fetching a backup with `docs +fetch` before overwriting.

The guard is best-effort: if the pre-fetch fails (network error, permission, etc.) the warning is silently skipped and the overwrite proceeds normally. The overwrite is never blocked — this is a warning only.

Test Plan

  • go test ./shortcuts/doc/... — all pass
  • go vet ./... — clean
  • gofmt -l . — clean

Summary by CodeRabbit

  • New Features

    • Added a best-effort pre-check that prints a non-blocking overwrite warning when overwriting documents that contain embedded whiteboards or file attachments; the check is skipped silently if the pre-fetch fails.
  • Tests

    • Added automated tests covering the overwrite-warning behavior and selection-title validation to ensure correct warnings and error messages.

Review Change Stack

… file blocks

Before executing an overwrite in v1 mode, pre-fetch the current document
and scan the Markdown for <whiteboard> and <file> resource blocks. If any
are found, print a warning to stderr listing the counts and suggesting the
user take a backup with `docs +fetch` first.

Overwrite replaces the entire document and cannot reconstruct these blocks
from Markdown; previously the data was lost with no indication to the caller.
The check is best-effort: a failed pre-fetch silently skips the guard rather
than blocking the overwrite.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 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: 0c9729e8-cee7-44d1-95a3-bc965e77667f

📥 Commits

Reviewing files that changed from the base of the PR and between 4d51bac and 977e057.

📒 Files selected for processing (1)
  • shortcuts/doc/docs_update.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/doc/docs_update.go

📝 Walkthrough

Walkthrough

Adds a best-effort pre-flight check for +update --mode overwrite: fetches the current document via MCP, scans for <whiteboard …> and <file …> blocks, and prints a non-blocking stderr warning summarizing counts if such blocks are found. Includes unit tests for the checker and title validation.

Changes

Overwrite Safety Guard

Layer / File(s) Summary
Resource Block Detection
shortcuts/doc/docs_update.go
checkOverwriteResourceBlocks counts occurrences of <whiteboard and <file tags in Markdown and returns a formatted warning string when blocks are found.
MCP Document Fetch & Check
shortcuts/doc/docs_update.go
warnOverwriteResourceBlocks calls the fetch-doc MCP tool in best-effort mode and delegates detection to checkOverwriteResourceBlocks; returns empty string on fetch failure.
Overwrite Guard Integration
shortcuts/doc/docs_update.go
executeUpdateV1 conditionally pre-fetches and warns before overwrite when --mode overwrite is set; warning is printed to stderr and does not block execution.
Tests & Support
shortcuts/doc/docs_update_test.go
Adds strings import, TestCheckOverwriteResourceBlocks table-driven tests validating warning presence and substrings across multiple markdown inputs, and TestValidateSelectionByTitleV1 table-driven tests for title validation errors.

Sequence Diagram

sequenceDiagram
  participant User
  participant executeUpdateV1
  participant warnOverwriteResourceBlocks
  participant MCP as fetch-doc_MCP_tool
  participant checkOverwriteResourceBlocks
  User->>executeUpdateV1: run update --mode overwrite
  executeUpdateV1->>warnOverwriteResourceBlocks: call to pre-flight check
  warnOverwriteResourceBlocks->>MCP: fetch-doc
  MCP-->>warnOverwriteResourceBlocks: current document markdown
  warnOverwriteResourceBlocks->>checkOverwriteResourceBlocks: scan markdown
  checkOverwriteResourceBlocks-->>warnOverwriteResourceBlocks: warning text (if any)
  warnOverwriteResourceBlocks-->>executeUpdateV1: warning string
  executeUpdateV1->>executeUpdateV1: print warning to stderr
  executeUpdateV1->>MCP: update-doc (proceed)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • larksuite/cli#569: Both PRs modify shortcuts/doc/docs_update.go’s DocsUpdate.Execute to emit non-blocking stderr warnings before the MCP update-doc call.

Suggested reviewers

  • fangshuyu-768
  • zkh-bytedance

Poem

🐰 I fetched the page with careful paws,
Counting whiteboards and files in the clause.
A soft little warning I tuck in your ear,
So your attachments won't vanish, my dear—
Hop on, commit safely, give a cheer!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% 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 specifically describes the main change: adding a warning before overwriting documents that contain whiteboard or file blocks.
Description check ✅ Passed The description is comprehensive, covering summary, changes, behavior with examples, and a complete test plan with checkmarks. It exceeds the template requirements.
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/docs-overwrite-resource-block-guard

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/ccm PR touches the ccm domain size/M Single-domain feat or fix with limited business impact labels May 11, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 11, 2026

Codecov Report

❌ Patch coverage is 68.42105% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.92%. Comparing base (25c72ce) to head (977e057).
⚠️ Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/doc/docs_update.go 68.42% 12 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #825      +/-   ##
==========================================
+ Coverage   65.67%   65.92%   +0.25%     
==========================================
  Files         513      518       +5     
  Lines       47655    48872    +1217     
==========================================
+ Hits        31297    32220     +923     
- Misses      13652    13885     +233     
- Partials     2706     2767      +61     

☔ 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 11, 2026

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/docs-overwrite-resource-block-guard -y -g

Copy link
Copy Markdown
Collaborator

@fangshuyu-768 fangshuyu-768 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! The best-effort warning design is sensible. I have a few concerns — the substring matching issue (#1) could lead to false positives and is worth addressing; the rest are suggestions.

Comment thread shortcuts/doc/docs_update.go Outdated
// warning string listing the counts if any are found, empty string otherwise.
func checkOverwriteResourceBlocks(markdown string) string {
var found []string
if n := strings.Count(markdown, "<whiteboard"); n > 0 {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Substring matching is too coarse — risk of false positives.

strings.Count(markdown, "<whiteboard") and strings.Count(markdown, "<file") can produce false matches:

  1. Text content: If the document contains prose mentioning whiteboards (e.g. a code example <whiteboard token="..."/>), it will be counted as a whiteboard block.
  2. <file prefix is overly broad: It could match <file-view>, <file-name>, or other tags that are not file attachment blocks.

Suggested fix — use a more precise regex:

var (
    whiteboardRe = regexp.MustCompile(`<whiteboard[\s/>]`)
    fileRe       = regexp.MustCompile(`<file[\s/>]`)
)

Or better yet, check block types directly via the document blocks API (/blocks) instead of scanning the Markdown representation.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 977e057. Replaced strings.Count with a regex <(whiteboard|file)[\s/>] that requires the tag name to be followed by whitespace, >, or / — so prose mentioning "whiteboard" or tags like <file-view> no longer match.

})
}

func TestValidateSelectionByTitleV1(t *testing.T) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unrelated test added in this PR.

TestValidateSelectionByTitleV1 tests validateSelectionByTitleV1, which is not part of this PR's changes. Unrelated tests should go in a separate PR to keep the diff focused and the review scoped.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Acknowledged. The test was added to improve patch coverage for the PR (codecov/patch was at 58.82%, below the 60% threshold) rather than because it is logically related to this change. Happy to move it to a separate follow-up PR if that is preferred, but since the function being tested (validateSelectionByTitleV1) lives in the same file and had zero test coverage, it felt like a reasonable addition in-place.

// Markdown. Pre-fetch the current content and warn when such blocks
// are present so the caller can take a backup before proceeding.
if runtime.Str("mode") == "overwrite" {
if w := warnOverwriteResourceBlocks(runtime); w != "" {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Extra latency from pre-fetch on every overwrite.

Every --mode overwrite call now incurs an additional fetch-doc MCP round-trip, even when the document has no resource blocks. This adds network latency to the critical path.

Consider:

  • Documenting the performance impact in the PR description or code comments
  • Making the guard opt-in via a flag (e.g. --warn-resource-loss) so callers who don't need the warning aren't penalized

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Documented in 977e057. Added a comment above warnOverwriteResourceBlocks explaining that every --mode overwrite call incurs one extra fetch-doc round-trip, that the cost is intentional, and why the trade-off is acceptable (best-effort, silent on failure, bounded latency).

// attachment blocks that would be permanently deleted by an overwrite. Returns
// an empty string (no warning) when the document is clean or the fetch fails
// (we never block the overwrite on a best-effort check).
func warnOverwriteResourceBlocks(runtime *common.RuntimeContext) string {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

warnOverwriteResourceBlocks lacks test coverage.

checkOverwriteResourceBlocks has thorough unit tests, but warnOverwriteResourceBlocks (the MCP integration layer) has none. While MCP calls are hard to mock, it would be helpful to either:

  • Add a comment explaining why it's not tested (best-effort, depends on external MCP call)
  • Provide a mock-based test for the happy path and the silent-failure-on-error path

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Documented in 977e057. Added a comment to warnOverwriteResourceBlocks explaining that it is not unit-tested because it depends on an external MCP call, and that the pure detection logic is fully covered by checkOverwriteResourceBlocks tests.

func warnOverwriteResourceBlocks(runtime *common.RuntimeContext) string {
args := map[string]interface{}{
"doc_id": runtime.Str("doc"),
"skip_task_detail": true,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

skip_task_detail: true lacks a comment.

The purpose of skip_task_detail is not self-evident. Please add a brief comment explaining why it's set (presumably to reduce response payload size and speed up the pre-fetch).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 977e057. Added an inline comment: // skip_task_detail reduces response payload by omitting per-block task metadata, making the pre-fetch faster and cheaper.

…e comments, document skip_task_detail purpose
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.

2 participants