Skip to content

feat: support whiteboard inline file import in docs create/update#1780

Open
SunPeiYang996 wants to merge 3 commits into
mainfrom
feature/lark-cli-whiteboard-relative-import
Open

feat: support whiteboard inline file import in docs create/update#1780
SunPeiYang996 wants to merge 3 commits into
mainfrom
feature/lark-cli-whiteboard-relative-import

Conversation

@SunPeiYang996

@SunPeiYang996 SunPeiYang996 commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Allow <whiteboard type="plantuml" path="@./diagram.puml"> in --content XML for docs +create and docs +update. CLI reads the file and replaces the tag body with the file content, consistent with the existing html5-block path="@..." resolution pattern.

Implementation

  • New whiteboard_inline.go: parse, validate, and rewrite <whiteboard> tags with @path attributes; infer type from file extension (.pumlplantuml, .mmdmermaid, .svgsvg, other→raw)
  • Wired into prepareDocsV2WriteInput (html5_block_resources.go) after html5-block processing
  • Validation: path and inner content are mutually exclusive
  • 7 unit tests: type validation, XML parsing, attribute operations, rendering

Test Plan

  • Full build passes
  • All doc package tests pass (no regression)
  • Test with lark-cli docs +create --content @./doc.xml --dry-run using a file containing <whiteboard type="plantuml" path="@./diagram.puml">
  • Test with real docs +create API call to verify whiteboard content is embedded in the created document

Summary by CodeRabbit

  • New Features
    • Added support for embedding whiteboard content directly in documents, including loading referenced files and ensuring the correct whiteboard type is applied.
  • Bug Fixes
    • Improved processing by validating whiteboard write element bodies and rejecting unsupported combinations of reference paths and inline content.
    • Enhanced handling of whiteboard reference resolution to produce more reliable document output.
  • Tests
    • Added coverage for whiteboard type validation, tag parsing/rendering, attribute handling, and related helpers.

Allow `<whiteboard type="plantuml" path="@./diagram.puml">` in --content
XML for docs +create and docs +update. CLI reads the file and replaces
the tag body with the file content, consistent with the existing
html5-block path resolution pattern.

- New whiteboard_inline.go: parse, validate, and rewrite whiteboard tags
  with @path attributes; infer type from file extension (.puml→plantuml,
  .mmd→mermaid, .svg→svg, other→raw)
- Wire into prepareDocsV2WriteInput (html5_block_resources.go) after
  html5-block processing
- Validate that path+inner content are mutually exclusive
- Add unit tests for type validation, XML parsing, attribute ops, rendering

Change-Id: Icf7f9efbec1385b956dd6d2e797895aaaeab141a
@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 Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 30ee70de-76ae-4bd6-b3d2-9c652d066819

📥 Commits

Reviewing files that changed from the base of the PR and between 764419e and 622a34c.

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

📝 Walkthrough

Walkthrough

This PR adds whiteboard element handling to the docs write pipeline. It validates <whiteboard> bodies, rewrites path-based whiteboard elements by loading referenced files, and adds helpers plus tests for parsing and rendering whiteboard start tags.

Changes

Whiteboard inline content feature

Layer / File(s) Summary
Pipeline wiring
shortcuts/doc/html5_block_resources.go
prepareDocsV2WriteInput now runs whiteboard body validation and inline-content preparation before resolving reference_map paths.
Tag structures and regex patterns
shortcuts/doc/whiteboard_inline.go
Defines the whiteboard tag constant, matching expressions, and internal structs for parsed attributes and start tags.
Inline content preparation and validation
shortcuts/doc/whiteboard_inline.go
Rewrites XML whiteboard elements from referenced files, validates allowed types, and rejects invalid or unsafe path="@..." usage.
Tag parsing and rendering helpers
shortcuts/doc/whiteboard_inline.go
Adds XML start-tag parsing plus attribute lookup, removal, and rendering helpers for whiteboard tags.
Unit tests
shortcuts/doc/whiteboard_inline_test.go
Adds tests covering type validation, start-tag parsing, attribute removal, rendering, and attribute presence checks.

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

Possibly related PRs

  • larksuite/cli#1690: Both PRs modify prepareDocsV2WriteInput in shortcuts/doc/html5_block_resources.go, with this change adding whiteboard validation and inlining into the same docs write flow.

Suggested reviewers: fangshuyu-768, MaxHuang22

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding whiteboard inline file import support for docs create/update.
Description check ✅ Passed The description covers the summary, implementation, and test plan, and is mostly aligned with the required template.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/lark-cli-whiteboard-relative-import

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 commented Jul 7, 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

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feature/lark-cli-whiteboard-relative-import -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: 5

🧹 Nitpick comments (2)
shortcuts/doc/whiteboard_inline_test.go (2)

94-104: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Only the non-self-closing render path is tested.

whiteboardStartTag.render is called with false here; the SelfClosing/render(true) path is not covered by any test in this file.

🤖 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/doc/whiteboard_inline_test.go` around lines 94 - 104, The
whiteboard start tag tests only cover the non-self-closing path in
whiteboardStartTag.render, so add coverage for the SelfClosing/render(true)
branch in the whiteboardStartTag.render tests. Use the existing
TestRenderWhiteboardStartTag pattern and the whiteboardStartTag.render method to
verify the emitted tag when SelfClosing is enabled, so both rendering paths are
exercised.

32-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing error-path coverage for parseWhiteboardStartTag.

All test cases have wantErr: false. The function has multiple error branches (tag-name mismatch, decode failure, missing start element) that are never exercised, so a regression there (e.g., silently accepting a non-<whiteboard> tag) would go undetected.

✅ Suggested additional case
 		{
 			name:    "no attributes",
 			raw:     `<whiteboard>`,
 			wantErr: false,
 			attrs:   map[string]string{},
 		},
+		{
+			name:    "wrong tag name",
+			raw:     `<html5-block path="@./x">`,
+			wantErr: true,
+		},
 	}
🤖 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/doc/whiteboard_inline_test.go` around lines 32 - 76, Add negative
test coverage to TestParseWhiteboardStartTag for the error branches in
parseWhiteboardStartTag: include cases that use a non-whiteboard tag, malformed
input that should fail XML decoding, and any input that should produce a missing
start element error. Keep the existing table-driven style and assert wantErr is
true for these cases so regressions in tag validation and parsing are caught.
🤖 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/html5_block_resources.go`:
- Around line 125-128: The whiteboard rewrite helper is shadowing the outer
docType, so the detected type never flows into the rewritten <whiteboard> tag.
Update the logic in the helper that prepares whiteboard inline content so it
assigns to the existing docType instead of redeclaring it, and make sure the tag
rewrite preserves type for path="@..." inputs. Add an end-to-end test around the
write path in prepareWhiteboardInlineContent/docsV2WriteInput to verify the type
attribute is retained.

In `@shortcuts/doc/whiteboard_inline.go`:
- Line 54: The whiteboard rewrite logic in rewriteWhiteboardStartTags only
updates the opening tag, which leaves the closing tag handling inconsistent and
breaks both normal and self-closing forms. Update the whiteboard transformation
path so it rewrites the entire <whiteboard> element consistently, including the
opening tag, embedded content, and closing behavior in the code paths around
rewriteWhiteboardStartTags, the closing-tag append logic, and the self-closing
handling branch. Ensure <whiteboard ...></whiteboard> does not get double-closed
and empty/self-closing whiteboards do not emit malformed extra closing markup.
- Around line 81-109: The inferred whiteboard type is computed in the whiteboard
tag rewrite logic but never written back to the tag, so path-only inputs lose
the type attribute. Update the handling in whiteboard_inline.go around the tag
attribute rewrite so that when docType is inferred from the file extension in
this branch, the tag’s attrs are updated to include type with that inferred
value; keep using the existing validation and rewrite flow in the same
whiteboard rewrite function.
- Line 122: Remove the unreachable return in the relevant function in
whiteboard_inline.go: the earlier return already exits the function, so the
trailing return content, nil should be deleted to satisfy go vet. Verify the
control flow around the existing return in the same function and keep only the
reachable exit path.
- Around line 190-193: The whiteboard file read path in the function handling
`@-prefixed` input currently returns a plain wrapped error from
cmdutil.ReadInputFile, but it should return a typed validation error like the
html5 block resource code. Update the read failure branch in
whiteboard_inline.go to use common.ValidationErrorf with the same user-facing
message and attach the underlying err via WithCause(err), and add a test
covering a missing or unreadable whiteboard file path.

---

Nitpick comments:
In `@shortcuts/doc/whiteboard_inline_test.go`:
- Around line 94-104: The whiteboard start tag tests only cover the
non-self-closing path in whiteboardStartTag.render, so add coverage for the
SelfClosing/render(true) branch in the whiteboardStartTag.render tests. Use the
existing TestRenderWhiteboardStartTag pattern and the whiteboardStartTag.render
method to verify the emitted tag when SelfClosing is enabled, so both rendering
paths are exercised.
- Around line 32-76: Add negative test coverage to TestParseWhiteboardStartTag
for the error branches in parseWhiteboardStartTag: include cases that use a
non-whiteboard tag, malformed input that should fail XML decoding, and any input
that should produce a missing start element error. Keep the existing
table-driven style and assert wantErr is true for these cases so regressions in
tag validation and parsing are caught.
🪄 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: ed3a755b-bb16-4fc1-9b6f-031986cbbb40

📥 Commits

Reviewing files that changed from the base of the PR and between f0b6f35 and 764419e.

📒 Files selected for processing (3)
  • shortcuts/doc/html5_block_resources.go
  • shortcuts/doc/whiteboard_inline.go
  • shortcuts/doc/whiteboard_inline_test.go

Comment thread shortcuts/doc/html5_block_resources.go
Comment thread shortcuts/doc/whiteboard_inline.go Outdated
Comment thread shortcuts/doc/whiteboard_inline.go
Comment thread shortcuts/doc/whiteboard_inline.go Outdated
Comment on lines +190 to +193
data, err := cmdutil.ReadInputFile(runtime.FileIO(), clean)
if err != nil {
return "", fmt.Errorf("%s %q cannot be read from the current working directory; check that the file exists: %w", label, clean, err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the local errs API shape and nearby file-I/O wrapping patterns.
rg -n "func ProblemOf|ProblemOf\\(|NewInternalError\\(errs\\.SubtypeFileIO" .
rg -n "ReadInputFile\\(|SubtypeFileIO" shortcuts internal cmd

Repository: larksuite/cli

Length of output: 48125


🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline shortcuts/doc/whiteboard_inline.go --view expanded
sed -n '1,260p' shortcuts/doc/whiteboard_inline.go

echo '--- internal/cmdutil/resolve.go ---'
sed -n '1,180p' internal/cmdutil/resolve.go

echo '--- nearby patterns ---'
sed -n '390,430p' shortcuts/doc/html5_block_resources.go

Repository: larksuite/cli

Length of output: 13674


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- shortcuts/doc/whiteboard_errors.go ---'
sed -n '1,120p' shortcuts/doc/whiteboard_errors.go

echo '--- shortcuts/doc/html5_block_resources.go (path helper) ---'
sed -n '400,430p' shortcuts/doc/html5_block_resources.go

echo '--- shortcuts/doc/whiteboard_inline.go imports + file helper ---'
sed -n '1,220p' shortcuts/doc/whiteboard_inline.go

echo '--- search for ValidationErrorf + WithCause in shortcuts/doc ---'
rg -n "ValidationErrorf\\(.*WithCause\\(|WithCause\\(err\\)" shortcuts/doc

Repository: larksuite/cli

Length of output: 272


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- common validation/error helpers ---'
rg -n "func ValidationErrorf|type ValidationError|WithCause\\(" shortcuts/common errs internal -g '*.go'

echo '--- file-path readers in shortcuts/doc ---'
rg -n "ReadInputFile\\(|ValidationErrorf\\(|NewInternalError\\(errs\\.SubtypeFileIO" shortcuts/doc -g '*.go'

echo '--- whiteboard-related files ---'
fd -a 'whiteboard*' shortcuts/doc

Repository: larksuite/cli

Length of output: 13655


Return a typed validation error for unreadable whiteboard files. cmdutil.ReadInputFile already returns a plain wrapped error here, so there’s no typed lower-layer error to pass through; match shortcuts/doc/html5_block_resources.go and use common.ValidationErrorf(...).WithCause(err) instead of fmt.Errorf(...) for @... file reads. Add a test for a missing/unreadable path.

🤖 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/doc/whiteboard_inline.go` around lines 190 - 193, The whiteboard
file read path in the function handling `@-prefixed` input currently returns a
plain wrapped error from cmdutil.ReadInputFile, but it should return a typed
validation error like the html5 block resource code. Update the read failure
branch in whiteboard_inline.go to use common.ValidationErrorf with the same
user-facing message and attach the underlying err via WithCause(err), and add a
test covering a missing or unreadable whiteboard file path.

Source: Coding guidelines

Comment thread shortcuts/doc/whiteboard_inline.go Fixed
Comment thread shortcuts/doc/whiteboard_inline.go Fixed
The previous approach matched only the start tag and appended a new closing
tag, leaving the original </whiteboard>. Use whiteboardElementReplacer that
matches the full element to avoid doubled closing tags.

Change-Id: Ib32fd487918e464fa875455690c165cc7d1dca6c
When the whiteboard type is inferred from file extension (e.g. .puml →
plantuml), the type attribute must be explicitly added to the tag attrs
so the server receives a valid <whiteboard type="plantuml"> tag.

Change-Id: Icfb4ec349ba47992be02ff90587e281fda143c73
@github-actions github-actions Bot added size/M Single-domain feat or fix with limited business impact and removed size/L Large or sensitive change across domains or core paths labels Jul 7, 2026
}

tag.removeAttrs("path")
if docType != "" {
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.

1 participant