Skip to content

fix(mail): hide lint counts + tip from default writepath envelope#834

Open
xulong3370 wants to merge 3 commits into
larksuite:mainfrom
xulong3370:harness/01kr5s4nvpv140b5k5ptfprpfn
Open

fix(mail): hide lint counts + tip from default writepath envelope#834
xulong3370 wants to merge 3 commits into
larksuite:mainfrom
xulong3370:harness/01kr5s4nvpv140b5k5ptfprpfn

Conversation

@xulong3370
Copy link
Copy Markdown

@xulong3370 xulong3370 commented May 11, 2026

Generated by the harness-coding skill.

  • Task ID: 01KR5S4NVPV140B5K5PTFPRPFN-14
  • Branch: harness/01kr5s4nvpv140b5k5ptfprpfn
  • Target: main

This branch is a fix-mode follow-up for PR #787 (which lives on a different fork that this worker cannot push to). It includes PR #787's full work as its base plus two surgical fixes the verify report demanded. Once this PR merges (or PR #787 is updated to incorporate these fixes), the feature ships with the default-envelope contract correctly enforced.

Sprints

ID Title Status Commit
S1 Fix bug A: gate lint_applied_count/original_blocked_count behind --show-lint-details passed d0b0489
S2 Fix bug B: remove unconditional tip field from buildDraftSavedOutput passed 0c5ebbb

What changed

Bug A — shortcuts/mail/mail_lint_writepath.go: moved data["lint_applied_count"] = len(applied) and data["original_blocked_count"] = len(blocked) inside the existing if showDetails {} block so all 4 lint fields (2 counts + 2 arrays) follow the same gating. This aligns the implementation with tech-design §4.1.5's "same in, same out" rule and the default-3-keys envelope contract.

Bug B — shortcuts/mail/helpers.go: removed the tip entry from buildDraftSavedOutput's returned map. The same teaching string is still emitted on stderr by hintSendDraft (see mail_send.go:306 et al.), so UX is unchanged. Test assertions in mail_send_confirm_output_test.go are flipped to require tip absent.

Source specs

  • /tmp/harness-agent/coding-dev/01KR5S4NVPV140B5K5PTFPRPFN/01KR5S4NVPV140B5K5PTFPRPFN-14/input/test-report.md

This MR was created autonomously. Quality gates were enforced by the repo's own pre-commit hooks.

Summary by CodeRabbit

  • New Features

    • Added +lint-html command for local HTML validation with optional auto-fix and strict-mode checking.
    • Integrated HTML linting into mail compose operations (+draft-create, +draft-edit, +forward, +reply, +reply-all, +send) to automatically sanitize unsafe markup and normalize legacy tags.
    • Added --show-lint-details flag to display detailed lint findings in command output.
    • Added email templates for job applications, weekly digests, market reports, and personal/team work reports.
  • Documentation

    • Published HTML email writing standards guide with compatibility rules and safe markup examples.
    • Added +lint-html usage documentation and guidelines for compose operations.

Review Change Stack

bubbmon233 and others added 3 commits May 8, 2026 22:06
Add an HTML lint library + Larksuite-native autofix to lark-cli mail, plus
the skills/lark-mail/ skill bundle (2 reference docs, 5 HTML templates, the
+lint-html shortcut, and writing-path lint integration across all 6 compose
shortcuts).

Lint library (shortcuts/mail/lint/)

- Error: drop dangerous tags (<script> / <iframe> / <form> / <input> /
  <link> / <object> / <embed>), on* event handlers, javascript: /
  vbscript: / file: URLs.
- Warning + autofix: rewrite HTML4-era <font> / <center> / <marquee> /
  <blink>.
- Larksuite-native autofix: rewrite <p> / <ul> / <ol> / <li> /
  <blockquote> / <a> to mail-editor native markup so AI can write the
  simplest HTML and still produce native-quality rendering.
- Inline-style and URL-scheme allow-list filtering.
- <style> block passthrough (server adds CSS scope class).

+lint-html shortcut (preview / CI)

Read-only HTML preview tool. Default envelope returns only cleaned_html;
--show-lint-details adds full warnings[] / errors[]. --strict exits non-
zero on any finding (CI gate).

Writing-path lint in 6 compose shortcuts

+send / +draft-create / +reply / +reply-all / +forward / +draft-edit body
op all run lint before drafting:

- lint_applied_count / original_blocked_count: always present.
- lint_applied[] / original_blocked[]: only with --show-lint-details.
- compose_hint: points AI consumers to the HTML writing guide.

skills/lark-mail/ skill bundle

5 pre-rendered Larksuite-native HTML templates: weekly newsletter,
personal weekly report, team weekly report, market research report,
résumé.

2 reference docs:
- references/lark-mail-html.md: writing rules + format primitives +
  template-usage flow.
- references/lark-mail-lint-html.md: +lint-html usage + return-value
  contract + 9 worked examples.

SKILL.md updates linking the new docs and templates.

Sealed conventions

- @user mention chip: id="at-user-N" is the only hard requirement; do
  not write data-user-id.
- Highlight palette: 3 colors (pink milestones, yellow follow-ups, green
  completed); black text, no bold / padding / border-radius.
- Brand color palette: main black, 3 levels of grey, Lark blue / deep
  blue, alert red, emergency orange, light pink / light grey
  backgrounds, border grey.
- URL scheme allow-list: http(s): / mailto: / cid: / data:image/* only.
- Inline-style + tag allow-lists.
- Writing-style floor: subject <= 50 chars, decision-first, lists instead
  of mechanical numbering, emoji only as status tags.

Tests

- shortcuts/mail/lint/...: unit tests for every rule.
- shortcuts/mail/mail_lint_html_test.go: +lint-html envelope contract.
- shortcuts/mail/mail_lint_writepath_test.go: writing-path envelope
  contract.
- 5 templates verified via +draft-create smoke test.
…ow-lint-details

The 2 count fields were unconditionally written into the writepath envelope's
data map, leaking lint metadata into the default-mode envelope and violating
the tech-design "same in, same out" rule for the 4 lint fields. Move them
inside the existing showDetails branch so all 4 lint fields (2 counts + 2
arrays) appear together only when the caller asks for detail.

Also updates applyLintToEnvelope's doc comment and the matching unit /
integration tests in mail_lint_writepath_test.go to assert the new
default-hidden behavior (counts now absent in default mode; present together
with arrays only when --show-lint-details=true).

sprint: S1
The tip text was unconditionally written into the JSON envelope returned by
buildDraftSavedOutput for +send / +reply / +reply-all / +forward save-as-draft
paths, but the tech-design only sanctions {compose_hint, draft_id, reference}
for the default envelope and never mentions tip. Drop tip from the .data map.
The same teaching string is still emitted on stderr by hintSendDraft, so user
UX is unchanged. Flip the matching test assertions to require tip absent.

sprint: S2
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive HTML linting and sanitization for mail composition via a new shortcuts/mail/lint library, a standalone +lint-html shortcut for local preview, integration into all compose shortcuts with shared write-path helpers, simplification of draft-save output envelopes, and extensive HTML writing guidelines with official templates.

Changes

Mail HTML Linting System

Layer / File(s) Summary
Lint Type Model
shortcuts/mail/lint/types.go
Introduces Severity (warning/error), Finding (rule ID, severity, tag/attribute, excerpt, hint), Options (AutoFix, Strict), and Report (Applied/Blocked findings, cleaned HTML, finding flags) with JSON marshaling contracts.
Classification Rules
shortcuts/mail/lint/rules.go
Defines 21 exported rule ID constants and implements classifyTag (allow/warn/error), classifyURLValue (scheme validation), classifyStyleProperty (CSS allowlist), and isEventHandlerAttr (DOM event detection).
Linting Engine
shortcuts/mail/lint/linter.go
Core Run() function with DOM parsing, element/attribute/style classification, warning-tier tag rewrites (font→span, center→div, marquee/blink→span with CSS distillation), Feishu-native styling post-pass, and fragment HTML rendering.
Linter Tests
shortcuts/mail/lint/linter_test.go
50+ unit tests covering allowed tags/styles pass-through, autofix behavior, strict mode, error-tier deletion, URL/CSS policies, report contracts, and classifier coverage.
Standalone +lint-html
shortcuts/mail/mail_lint_html.go
New shortcut with --body / --body-file (mutually exclusive), --auto-fix (default true), --strict (non-zero exit on findings), --show-lint-details (include arrays), path safety validation, and pretty-print formatting.
+lint-html Tests
shortcuts/mail/mail_lint_html_test.go
13 end-to-end tests for flag validation, path safety, HTML cleaning, envelope shape differences, strict mode, plain-text short-circuit, and finding schema.
Write-Path Lint Helpers
shortcuts/mail/mail_lint_writepath.go
Shared helpers: runWritePathLint() (AutoFix=true, Strict=false), applyLintToEnvelope() (conditional field population), and addComposeHint() for lint integration across compose shortcuts.
Write-Path Tests
shortcuts/mail/mail_lint_writepath_test.go
Unit and end-to-end tests for helper behavior and +draft-create integration verifying lint field hiding by default, exposure via flag, and safety transformations before EML submission.

Compose Shortcut Integration

Layer / File(s) Summary
+draft-create Lint
shortcuts/mail/mail_draft_create.go
buildRawEMLForDraftCreate signature changed to return (rawEML, lintApplied, lintBlocked, err); HTML path runs runWritePathLint after signature injection; Execute applies lint results via applyLintToEnvelope controlled by --show-lint-details.
+draft-create Tests
shortcuts/mail/mail_draft_create_test.go
10 tests updated to unpack four return values from buildRawEMLForDraftCreate while preserving all existing assertion logic.
+draft-edit, +forward, +reply, +reply-all, +send
shortcuts/mail/mail_draft_edit.go, mail_forward.go, mail_reply.go, mail_reply_all.go, mail_send.go
Each shortcut adds showLintDetailsFlag, initializes lint envelope fields, runs runWritePathLint on composed HTML body (excluding pre-quoted content), and applies lint results to output envelopes before writing stdout.

Output Envelope Simplification

Layer / File(s) Summary
Draft Saved Output
shortcuts/mail/helpers.go
buildDraftSavedOutput changed to emit minimal JSON envelope (only draft_id and optional reference); removed embedded tip field; hint emitted elsewhere.
Output Tests
shortcuts/mail/mail_send_confirm_output_test.go
Test expectations updated to assert absence of tip key in both reference-present and reference-absent cases.

Registry and Documentation

Layer / File(s) Summary
Shortcut Registry
shortcuts/mail/shortcuts.go
Added MailLintHTML to returned shortcut slice.
HTML Writing Rules & Lint Guide
skills/lark-mail/references/lark-mail-html.md, lark-mail-lint-html.md, shortcut references, skill-template/domains/mail.md
Comprehensive HTML/CSS/URL writing specifications with examples, lint contract explanation, +lint-html usage, and pre-read requirements for all compose shortcuts.
Official Email Templates
skills/lark-mail/assets/templates/*.html
Five new templates (resume, newsletter, market report, personal report, team report) with placeholders and styling guidance.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • larksuite/cli#595: Both PRs modify draft-save output behavior—moving hint text from JSON envelopes to stderr and introducing new hint helper functions.

Suggested labels

domain/mail, size/S

Suggested reviewers

  • chanthuang
  • infeng
  • haidaodashushu

Poem

🐰 A rabbit hops through tangled tags,
Cleaning lint from mail-compose bags,
<font> becomes a <span> so neat,
HTML safety, now complete!
Feishu-native, tests in place—
Every email, a cleaner case. ✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@github-actions github-actions Bot added domain/mail PR touches the mail domain size/XL Architecture-level or global-impact change labels May 11, 2026
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: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
skills/lark-mail/references/lark-mail-send.md (1)

107-109: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Documentation inconsistent with PR Bug B fix.

According to the PR objectives, Bug B removes the tip entry from buildDraftSavedOutput's returned map (the stdout JSON envelope). However, line 108 still shows "tip" in the 草稿模式 return value example. Per the PR summary, the tip string is now emitted on stderr by hintSendDraft instead, so the JSON envelope should only contain draft_id (and optionally reference when available, per line 113).

📋 Proposed fix to align with Bug B
 ```json
 {
   "ok": true,
   "data": {
-    "draft_id": "草稿ID",
-    "tip": "draft saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'"
+    "draft_id": "草稿ID"
   }
 }

Add a note below the example explaining that the hint message is now printed to stderr instead.
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @skills/lark-mail/references/lark-mail-send.md around lines 107 - 109, Update
the 草稿模式 JSON example to match Bug B by removing the "tip" entry from the
buildDraftSavedOutput stdout envelope (so only "draft_id" and optionally
"reference" remain), and add a brief note below the example stating that the
hint message is now emitted to stderr by hintSendDraft; ensure you reference
buildDraftSavedOutput and hintSendDraft so reviewers can locate the related
behavior.


</details>

</blockquote></details>
<details>
<summary>skills/lark-mail/references/lark-mail-reply.md (1)</summary><blockquote>

`98-100`: _⚠️ Potential issue_ | _🟠 Major_ | _⚡ Quick win_

**Documentation inconsistent with PR Bug B fix.**

Line 99 still shows the `"tip"` field, but this was removed from the default envelope per PR Bug B.




<details>
<summary>📋 Proposed fix</summary>

```diff
 ```json
 {
   "ok": true,
   "data": {
-    "draft_id": "草稿ID",
-    "tip": "draft saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'"
+    "draft_id": "草稿ID"
   }
 }
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @skills/lark-mail/references/lark-mail-reply.md around lines 98 - 100, The
documentation example still includes the removed "tip" field; update the JSON
example in lark-mail-reply.md so the response object only contains "draft_id"
under "data" (remove the "tip" entry and its message), and ensure any
surrounding explanatory text or example output references are adjusted to match
the new envelope returned by the code that only returns "draft_id".


</details>

</blockquote></details>
<details>
<summary>skills/lark-mail/references/lark-mail-reply-all.md (1)</summary><blockquote>

`95-97`: _⚠️ Potential issue_ | _🟠 Major_ | _⚡ Quick win_

**Documentation inconsistent with PR Bug B fix.**

Line 96 still shows the `"tip"` field in the default envelope, but PR Bug B removes this field.




<details>
<summary>📋 Proposed fix</summary>

```diff
 ```json
 {
   "ok": true,
   "data": {
-    "draft_id": "草稿ID",
-    "tip": "draft saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'"
+    "draft_id": "草稿ID"
   }
 }
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @skills/lark-mail/references/lark-mail-reply-all.md around lines 95 - 97,
Remove the obsolete "tip" field from the default response envelope used in the
reply-all reference example: update the JSON sample that currently shows both
"draft_id" and "tip" to only include "draft_id" (i.e., delete the "tip": "draft
saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'" entry)
so the example matches the PR Bug B change.


</details>

</blockquote></details>
<details>
<summary>skills/lark-mail/references/lark-mail-forward.md (1)</summary><blockquote>

`93-96`: _⚠️ Potential issue_ | _🟠 Major_ | _⚡ Quick win_

**Documentation inconsistent with PR Bug B fix.**

Line 95 still shows the `"tip"` field in the 草稿模式 return value, but PR Bug B removes this field from the default envelope. The tip message is now emitted on stderr instead.




<details>
<summary>📋 Proposed fix</summary>

```diff
 ```json
 {
   "ok": true,
   "data": {
-    "draft_id": "草稿ID",
-    "tip": "draft saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'"
+    "draft_id": "草稿ID"
   }
 }
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @skills/lark-mail/references/lark-mail-forward.md around lines 93 - 96,
Update the example JSON in skills/lark-mail/references/lark-mail-forward.md to
match PR Bug B by removing the now-removed "tip" field from the 草稿模式 return
value; locate the JSON object containing "draft_id" and remove the "tip": "draft
saved. To send: lark-cli mail user_mailbox.drafts send --params '{...}'" entry
so the returned data only includes "draft_id".


</details>

</blockquote></details>

</blockquote></details>
🧹 Nitpick comments (1)
shortcuts/mail/mail_send_confirm_output_test.go (1)

90-104: ⚡ Quick win

Cover the stderr handoff in the regression test.

These assertions only prove that tip disappeared from the JSON map. Please add one save-draft integration assertion that the send hint still lands on stderr, so the channel split itself cannot regress.

As per coding guidelines stdout is data (JSON envelopes), stderr is everything else (progress, warnings, hints). Never mix them as it corrupts pipe chains.

🤖 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/mail/mail_send_confirm_output_test.go` around lines 90 - 104, The
test currently only asserts that "tip" is omitted from the JSON envelope
produced by buildDraftSavedOutput/DraftResult, but doesn't verify that the "send
hint" is still written to stderr; update mail_send_confirm_output_test.go to
capture the process stderr when exercising the save-draft path (the same
invocation that calls buildDraftSavedOutput or the helper that executes the
save-draft flow) and add an assertion that stderr contains the expected send
hint text (e.g., the hint string used when saving drafts), while keeping the
existing stdout JSON assertions to ensure the channel split (stdout for JSON
envelope, stderr for hints) is preserved.
🤖 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/mail/lint/linter.go`:
- Around line 69-75: Finalize strict-mode promotion (Options.Strict) before
calculating rep.HasErrorFindings and rep.HasWarningFindings: after walk(...) and
applyFeishuNativeStyles(...) but before setting
rep.HasErrorFindings/rep.HasWarningFindings, run the normalization step that
promotes warning severities to error for findings (e.g., transform entries in
rep.Applied and any STYLE_PROPERTY_DROPPED or Feishu-native rewrite findings)
when Options.Strict is true so the subsequent flags reflect the promoted
severities; ensure you update the severity fields on rep.Applied/rep.Blocked as
needed and then compute rep.HasErrorFindings = len(rep.Blocked) > 0 and
rep.HasWarningFindings = len(rep.Applied) > 0.
- Around line 735-738: The code declares and populates a local map variable
named `priority` (created with make(map[string]int, len(order)) and filled in
the loop `for i, k := range order { priority[strings.ToLower(k)] = i + 1 }`) but
never uses it; remove the unused `priority` declaration and the entire loop that
fills it to fix the unused-local compile error, or if the map is intended to be
used later, replace its usage appropriately where `priority` is referenced
instead of deleting—ensure no other code expects `priority` after removal.

In `@shortcuts/mail/lint/rules.go`:
- Around line 201-241: The scheme-cleaning step currently removes control bytes
but leaves plain spaces (U+0020), so inputs like "java script:..." are
misclassified; update the rune filter in the strings.Map call (the block that
assigns value by mapping runes) to also drop U+0020 (space) so the subsequent
colon search and scheme extraction (scheme := strings.ToLower(value[:colon]))
treat embedded spaces as removed; ensure this change still preserves removal of
control bytes and DEL and keeps the rest of the logic around allowedURLSchemes,
blockedURLSchemes and the "data" handling intact.

In `@shortcuts/mail/mail_lint_writepath.go`:
- Around line 19-23: The help text for the flag showLintDetailsFlag is
misleading: update its Desc to state that lint fields are omitted by default and
only included when --show-lint-details=true to match applyLintToEnvelope
behavior; edit the Desc for the variable showLintDetailsFlag to clearly say that
the four lint fields (lint_applied, original_blocked and their counts) are
omitted unless the flag is true, referencing the applyLintToEnvelope logic that
controls inclusion.

In `@skills/lark-mail/assets/templates/job-application--resume.html`:
- Around line 16-23: The template contains invalid nested list wrappers like
repeated "<ul data-list-bullet=\"true\">...<ul
data-list-bullet=\"true\">...</ul></ul>" and "<ol ...
data-list-number=\"true\">...<ol ...>...</ol></ol>" which produce non-LI
children; update the HTML so each list wrapper only directly contains <li>
elements by either flattening the pair into a single indented <ul> or <ol>
(remove the outer/inner duplicate wrapper), or move the inner list inside a real
<li> (so the inner "<ul>" becomes a child of a corresponding "<li
class=\"temp-li ...\">"); ensure instances with class="temp-li bullet2" and
data-ol-id="work"/"proj" follow this rule and keep styling attributes on the
remaining valid list elements.

In `@skills/lark-mail/references/lark-mail-draft-create.md`:
- Line 11: The link in the CRITICAL prerequisite currently points to
"references/lark-mail-html.md" but the correct relative target is the sibling
file "lark-mail-html.md"; update the markdown link text to reference
"lark-mail-html.md" (replace "references/lark-mail-html.md" with
"lark-mail-html.md") wherever it appears in the CRITICAL line so the
prerequisite points to the correct file in the same directory.

In `@skills/lark-mail/references/lark-mail-draft-edit.md`:
- Line 15: The CRITICAL note currently links to "references/lark-mail-html.md"
which is incorrect for this directory; update the Markdown link target in the
note (the string "references/lark-mail-html.md") to a same-directory relative
path such as "./lark-mail-html.md" (or "lark-mail-html.md") so the link resolves
correctly from skills/lark-mail/references/lark-mail-draft-edit.md.

In `@skills/lark-mail/references/lark-mail-forward.md`:
- Around line 16-17: The markdown has an unmatched closing bold marker in the
sentence "编辑邮件内容前 MUST 先用 Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**" — fix
by removing the trailing "**" or by adding a matching opening "**" before the
text you intend to bold (update the line containing that sentence in
lark-mail-forward.md so bold markers are balanced).

In `@skills/lark-mail/references/lark-mail-reply-all.md`:
- Around line 16-17: The markdown line containing "编辑邮件内容前 MUST 先用 Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**" has
an unmatched closing bold marker; fix it by either removing the trailing "**" or
adding a matching opening "**" before the intended bold text so the Markdown is
valid—update the sentence in lark-mail-reply-all.md accordingly to use proper
bold markers.

In `@skills/lark-mail/references/lark-mail-reply.md`:
- Around line 20-21: The markdown line ending with an unmatched bold delimiter
("编辑邮件内容前 MUST 先用 Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**") has
a stray closing **; fix by either removing the trailing ** or adding a matching
opening ** before the intended bolded text so the bold markup is balanced (edit
the sentence text fragment shown to ensure matching ** delimiters).

In `@skills/lark-mail/references/lark-mail-send.md`:
- Around line 15-16: The line "编辑邮件内容前 MUST 先用 Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**" has a
stray closing bold marker (**); fix the malformed bold by either removing the
trailing "**" or by adding a matching opening "**" before the text you intend to
bold so the markdown becomes balanced—update the sentence in the
lark-mail-send.md content accordingly.

---

Outside diff comments:
In `@skills/lark-mail/references/lark-mail-forward.md`:
- Around line 93-96: Update the example JSON in
skills/lark-mail/references/lark-mail-forward.md to match PR Bug B by removing
the now-removed "tip" field from the 草稿模式 return value; locate the JSON object
containing "draft_id" and remove the "tip": "draft saved. To send: lark-cli mail
user_mailbox.drafts send --params '{...}'" entry so the returned data only
includes "draft_id".

In `@skills/lark-mail/references/lark-mail-reply-all.md`:
- Around line 95-97: Remove the obsolete "tip" field from the default response
envelope used in the reply-all reference example: update the JSON sample that
currently shows both "draft_id" and "tip" to only include "draft_id" (i.e.,
delete the "tip": "draft saved. To send: lark-cli mail user_mailbox.drafts send
--params '{...}'" entry) so the example matches the PR Bug B change.

In `@skills/lark-mail/references/lark-mail-reply.md`:
- Around line 98-100: The documentation example still includes the removed "tip"
field; update the JSON example in lark-mail-reply.md so the response object only
contains "draft_id" under "data" (remove the "tip" entry and its message), and
ensure any surrounding explanatory text or example output references are
adjusted to match the new envelope returned by the code that only returns
"draft_id".

In `@skills/lark-mail/references/lark-mail-send.md`:
- Around line 107-109: Update the 草稿模式 JSON example to match Bug B by removing
the "tip" entry from the buildDraftSavedOutput stdout envelope (so only
"draft_id" and optionally "reference" remain), and add a brief note below the
example stating that the hint message is now emitted to stderr by hintSendDraft;
ensure you reference buildDraftSavedOutput and hintSendDraft so reviewers can
locate the related behavior.

---

Nitpick comments:
In `@shortcuts/mail/mail_send_confirm_output_test.go`:
- Around line 90-104: The test currently only asserts that "tip" is omitted from
the JSON envelope produced by buildDraftSavedOutput/DraftResult, but doesn't
verify that the "send hint" is still written to stderr; update
mail_send_confirm_output_test.go to capture the process stderr when exercising
the save-draft path (the same invocation that calls buildDraftSavedOutput or the
helper that executes the save-draft flow) and add an assertion that stderr
contains the expected send hint text (e.g., the hint string used when saving
drafts), while keeping the existing stdout JSON assertions to ensure the channel
split (stdout for JSON envelope, stderr for hints) is preserved.
🪄 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: 719573fe-2cdd-4724-b6a9-28d36b93c7ac

📥 Commits

Reviewing files that changed from the base of the PR and between db1a3fc and 0c5ebbb.

📒 Files selected for processing (33)
  • shortcuts/mail/helpers.go
  • shortcuts/mail/lint/linter.go
  • shortcuts/mail/lint/linter_test.go
  • shortcuts/mail/lint/rules.go
  • shortcuts/mail/lint/types.go
  • shortcuts/mail/mail_draft_create.go
  • shortcuts/mail/mail_draft_create_test.go
  • shortcuts/mail/mail_draft_edit.go
  • shortcuts/mail/mail_forward.go
  • shortcuts/mail/mail_lint_html.go
  • shortcuts/mail/mail_lint_html_test.go
  • shortcuts/mail/mail_lint_writepath.go
  • shortcuts/mail/mail_lint_writepath_test.go
  • shortcuts/mail/mail_reply.go
  • shortcuts/mail/mail_reply_all.go
  • shortcuts/mail/mail_send.go
  • shortcuts/mail/mail_send_confirm_output_test.go
  • shortcuts/mail/shortcuts.go
  • skill-template/domains/mail.md
  • skills/lark-mail/SKILL.md
  • skills/lark-mail/assets/templates/job-application--resume.html
  • skills/lark-mail/assets/templates/newsletter--weekly-brief.html
  • skills/lark-mail/assets/templates/research--market-report.html
  • skills/lark-mail/assets/templates/weekly--personal-report.html
  • skills/lark-mail/assets/templates/weekly--team-report.html
  • skills/lark-mail/references/lark-mail-draft-create.md
  • skills/lark-mail/references/lark-mail-draft-edit.md
  • skills/lark-mail/references/lark-mail-forward.md
  • skills/lark-mail/references/lark-mail-html.md
  • skills/lark-mail/references/lark-mail-lint-html.md
  • skills/lark-mail/references/lark-mail-reply-all.md
  • skills/lark-mail/references/lark-mail-reply.md
  • skills/lark-mail/references/lark-mail-send.md

Comment on lines +69 to +75
walk(root, &rep, opts)
applyFeishuNativeStyles(root, &rep, opts)

rep.HasErrorFindings = len(rep.Blocked) > 0
rep.HasWarningFindings = len(rep.Applied) > 0
rep.CleanedHTML = renderFragment(root)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Finalize strict-mode promotion before computing the report flags.

Options.Strict is documented as promoting warnings to errors, but STYLE_PROPERTY_DROPPED and the Feishu-native rewrite findings can still reach this point in Applied with warning severity. That makes +lint-html --strict report different severities depending on which path produced the finding.

Suggested normalization point
  walk(root, &rep, opts)
  applyFeishuNativeStyles(root, &rep, opts)
+
+ if opts.Strict && len(rep.Applied) > 0 {
+ 	promoted := make([]Finding, len(rep.Applied))
+ 	copy(promoted, rep.Applied)
+ 	for i := range promoted {
+ 		promoted[i].Severity = SeverityError
+ 	}
+ 	rep.Blocked = append(rep.Blocked, promoted...)
+ 	rep.Applied = rep.Applied[:0]
+ }
 
  rep.HasErrorFindings = len(rep.Blocked) > 0
  rep.HasWarningFindings = len(rep.Applied) > 0
  rep.CleanedHTML = renderFragment(root)
🤖 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/mail/lint/linter.go` around lines 69 - 75, Finalize strict-mode
promotion (Options.Strict) before calculating rep.HasErrorFindings and
rep.HasWarningFindings: after walk(...) and applyFeishuNativeStyles(...) but
before setting rep.HasErrorFindings/rep.HasWarningFindings, run the
normalization step that promotes warning severities to error for findings (e.g.,
transform entries in rep.Applied and any STYLE_PROPERTY_DROPPED or Feishu-native
rewrite findings) when Options.Strict is true so the subsequent flags reflect
the promoted severities; ensure you update the severity fields on
rep.Applied/rep.Blocked as needed and then compute rep.HasErrorFindings =
len(rep.Blocked) > 0 and rep.HasWarningFindings = len(rep.Applied) > 0.

Comment on lines +735 to +738
priority := make(map[string]int, len(order))
for i, k := range order {
priority[strings.ToLower(k)] = i + 1
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
sed -n '731,762p' shortcuts/mail/lint/linter.go

python - <<'PY'
from pathlib import Path
import re

text = Path("shortcuts/mail/lint/linter.go").read_text()
m = re.search(r'func reorderAttrs\(n \*xhtml\.Node, order \[\]string\) \{(?P<body>.*?)^\}', text, re.S | re.M)
body = m.group("body")
for i, line in enumerate(body.splitlines(), 1):
    if "priority" in line:
        print(f"{i}: {line}")
PY

Repository: larksuite/cli

Length of output: 919


Remove the unused priority map declaration and initialization.

The priority variable is populated in a loop but never read. Go rejects unused locals, so this code will not compile until these lines are removed.

Suggested fix
-	priority := make(map[string]int, len(order))
-	for i, k := range order {
-		priority[strings.ToLower(k)] = i + 1
-	}
 	sorted := make([]xhtml.Attribute, 0, len(n.Attr))
 	used := make([]bool, len(n.Attr))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
priority := make(map[string]int, len(order))
for i, k := range order {
priority[strings.ToLower(k)] = i + 1
}
🤖 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/mail/lint/linter.go` around lines 735 - 738, The code declares and
populates a local map variable named `priority` (created with
make(map[string]int, len(order)) and filled in the loop `for i, k := range order
{ priority[strings.ToLower(k)] = i + 1 }`) but never uses it; remove the unused
`priority` declaration and the entire loop that fills it to fix the unused-local
compile error, or if the map is intended to be used later, replace its usage
appropriately where `priority` is referenced instead of deleting—ensure no other
code expects `priority` after removal.

Comment on lines +201 to +241
// Strip leading whitespace + control bytes that could obscure the
// scheme (e.g. "java\tscript:..."). The html-parser already strips
// stray whitespace at attribute boundaries; this is defence-in-depth
// for older clients that paste from Word with U+0009 / U+0020 inside
// the scheme prefix.
value = strings.Map(func(r rune) rune {
if r < 0x20 || r == 0x7F {
return -1
}
return r
}, value)

// Find the colon delimiter; everything before it is the scheme.
colon := strings.IndexByte(value, ':')
if colon < 0 {
// No scheme → relative URL → allow.
return "ok", ""
}
scheme := strings.ToLower(value[:colon])
rest := value[colon+1:]

switch {
case allowedURLSchemes[scheme]:
return "ok", ""
case scheme == "data":
// data:image/* is whitelisted; anything else (e.g. data:text/html;...)
// is rejected. The check tolerates any subtype under image/* (png /
// jpeg / gif / svg+xml / webp) so users embedding base64 thumbnails
// don't trip the rule.
rest = strings.TrimSpace(rest)
if strings.HasPrefix(strings.ToLower(rest), "image/") {
return "ok", ""
}
return "error", RuleAttrJSURLBlocked
case blockedURLSchemes[scheme]:
return "error", RuleAttrJSURLBlocked
default:
// Unknown scheme: surface a warning so users see it but don't
// drop legitimate webcal:/tel: / similar in case downstream
// renders eventually support them.
return "warn", RuleAttrUnsafeSchemeBlocked
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Strip plain spaces from the scheme prefix before classification.

The hardening comment says U+0020 inside the scheme should be ignored, but this mapper only removes bytes < 0x20. Inputs like href="java script:alert(1)" therefore fall into the unknown-scheme path instead of the blocked-scheme 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/mail/lint/rules.go` around lines 201 - 241, The scheme-cleaning
step currently removes control bytes but leaves plain spaces (U+0020), so inputs
like "java script:..." are misclassified; update the rune filter in the
strings.Map call (the block that assigns value by mapping runes) to also drop
U+0020 (space) so the subsequent colon search and scheme extraction (scheme :=
strings.ToLower(value[:colon])) treat embedded spaces as removed; ensure this
change still preserves removal of control bytes and DEL and keeps the rest of
the logic around allowedURLSchemes, blockedURLSchemes and the "data" handling
intact.

Comment on lines +19 to +23
var showLintDetailsFlag = common.Flag{
Name: "show-lint-details",
Type: "bool",
Desc: "Include the full lint_applied[] / original_blocked[] arrays in the envelope. Default: only counts (lint_applied_count / original_blocked_count) are returned to keep the envelope small.",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update --show-lint-details help text to match current behavior.

Line 22 says default mode returns counts, but applyLintToEnvelope (Line 79-84) now omits all four lint fields unless --show-lint-details=true. The flag description should be updated to avoid misleading users.

✏️ Suggested text fix
 var showLintDetailsFlag = common.Flag{
 	Name: "show-lint-details",
 	Type: "bool",
-	Desc: "Include the full lint_applied[] / original_blocked[] arrays in the envelope. Default: only counts (lint_applied_count / original_blocked_count) are returned to keep the envelope small.",
+	Desc: "Include lint details in the envelope: lint_applied_count, original_blocked_count, lint_applied[], and original_blocked[]. Default: these fields are omitted to keep the envelope small.",
 }
🤖 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/mail/mail_lint_writepath.go` around lines 19 - 23, The help text
for the flag showLintDetailsFlag is misleading: update its Desc to state that
lint fields are omitted by default and only included when
--show-lint-details=true to match applyLintToEnvelope behavior; edit the Desc
for the variable showLintDetailsFlag to clearly say that the four lint fields
(lint_applied, original_blocked and their counts) are omitted unless the flag is
true, referencing the applyLintToEnvelope logic that controls inclusion.

Comment on lines +16 to +23
<ul data-list-bullet="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><ul data-list-bullet="true" style="margin:0px 0px 0px 24px;padding-left:0px;list-style-position:inside"><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[工作职责描述 1:聚焦动作 + 产出,附数据 / 影响范围]</span></span></li><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[工作职责描述 2:核心成果 + 关键技术 / 方法]</span></span></li><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[工作职责描述 3]</span></span></li></ul></ul>
<ol start="2" data-list-number="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><li class="temp-li number1" data-li-line="true" data-list="number1" data-ol-id="work" data-start="2" style="line-height:1.6;margin-top:4px;margin-bottom:4px;padding-left:0px;display:list-item;list-style-type:decimal;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><b><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[公司名称]</span></span></b><span style="font-family:inherit"><span style="color:rgb(31,35,41)"> · [职位] · [全职 / 实习 / 兼职]</span></span><span style="font-family:inherit"><span style="color:rgb(143,149,158);font-size:13px"> · [YYYY-MM] ~ [YYYY-MM]</span></span></li></ol>
<ul data-list-bullet="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><ul data-list-bullet="true" style="margin:0px 0px 0px 24px;padding-left:0px;list-style-position:inside"><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[工作职责描述 1]</span></span></li><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[工作职责描述 2]</span></span></li></ul></ul>
<div style="margin-top:24px;margin-bottom:12px;line-height:1.6"><div dir="auto" style="font-size:14px;border-bottom:1px solid rgb(222,224,227);padding-bottom:6px"><b><span style="font-size:16px"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">项目经历</span></span></span></b></div></div>
<ol start="1" data-list-number="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><li class="temp-li number1" data-li-line="true" data-list="number1" data-ol-id="proj" data-start="1" style="line-height:1.6;margin-top:4px;margin-bottom:4px;padding-left:0px;display:list-item;list-style-type:decimal;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><b><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[项目名称]</span></span></b><span style="font-family:inherit"><span style="color:rgb(31,35,41)"> · [角色,如 负责人 / 核心开发 / 设计主导]</span></span><span style="font-family:inherit"><span style="color:rgb(143,149,158);font-size:13px"> · [YYYY-MM] ~ [YYYY-MM]</span></span></li></ol>
<ul data-list-bullet="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><ul data-list-bullet="true" style="margin:0px 0px 0px 24px;padding-left:0px;list-style-position:inside"><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[项目背景 / 业务价值 1 句话]</span></span></li><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[关键贡献 / 技术栈]</span></span></li><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[项目成果 / 数据指标]</span></span></li></ul></ul>
<ol start="2" data-list-number="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><li class="temp-li number1" data-li-line="true" data-list="number1" data-ol-id="proj" data-start="2" style="line-height:1.6;margin-top:4px;margin-bottom:4px;padding-left:0px;display:list-item;list-style-type:decimal;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><b><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[项目名称]</span></span></b><span style="font-family:inherit"><span style="color:rgb(31,35,41)"> · [角色]</span></span><span style="font-family:inherit"><span style="color:rgb(143,149,158);font-size:13px"> · [YYYY-MM] ~ [YYYY-MM]</span></span></li></ol>
<ul data-list-bullet="true" style="margin-top:0px;margin-bottom:0px;margin-left:0px;padding-left:0px;list-style-position:inside"><ul data-list-bullet="true" style="margin:0px 0px 0px 24px;padding-left:0px;list-style-position:inside"><li class="temp-li bullet2" data-li-line="true" data-list="bullet2" style="line-height:1.6;margin-top:2px;margin-bottom:2px;padding-left:0px;display:list-item;list-style-type:circle;font-family:inherit;font-size:14px;margin-left:0px;list-style-position:inside" dir="auto"><span style="font-family:inherit"><span style="color:rgb(31,35,41)">[项目描述 + 关键贡献 + 成果数据]</span></span></li></ul></ul>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix the invalid nested list structure.

These sections currently render as <ul><ul>...</ul></ul>, but a <ul> may only contain <li> children. Mail renderers repair that markup differently, so bullets and spacing can drift or disappear. Flatten each pair to a single indented list, or nest the inner list inside a real <li>.

🤖 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 `@skills/lark-mail/assets/templates/job-application--resume.html` around lines
16 - 23, The template contains invalid nested list wrappers like repeated "<ul
data-list-bullet=\"true\">...<ul data-list-bullet=\"true\">...</ul></ul>" and
"<ol ... data-list-number=\"true\">...<ol ...>...</ol></ol>" which produce
non-LI children; update the HTML so each list wrapper only directly contains
<li> elements by either flattening the pair into a single indented <ul> or <ol>
(remove the outer/inner duplicate wrapper), or move the inner list inside a real
<li> (so the inner "<ul>" becomes a child of a corresponding "<li
class=\"temp-li ...\">"); ensure instances with class="temp-li bullet2" and
data-ol-id="work"/"proj" follow this rule and keep styling attributes on the
remaining valid list elements.


**正文编辑和其他高级操作必须通过 `--patch-file`**。没有 `--set-body` flag。

**CRITICAL - 编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the relative link target in the new CRITICAL note.

Line 15 links to references/lark-mail-html.md, which is incorrect from this directory and likely broken. Use a same-directory relative link instead.

🔗 Suggested fix
-**CRITICAL - 编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
+**CRITICAL - 编辑邮件内容前 MUST 先用 Read 工具读取 [lark-mail-html.md](lark-mail-html.md),其中包含邮件书写规范**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**CRITICAL - 编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
**CRITICAL - 编辑邮件内容前 MUST 先用 Read 工具读取 [lark-mail-html.md](lark-mail-html.md),其中包含邮件书写规范**
🤖 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 `@skills/lark-mail/references/lark-mail-draft-edit.md` at line 15, The CRITICAL
note currently links to "references/lark-mail-html.md" which is incorrect for
this directory; update the Markdown link target in the note (the string
"references/lark-mail-html.md") to a same-directory relative path such as
"./lark-mail-html.md" (or "lark-mail-html.md") so the link resolves correctly
from skills/lark-mail/references/lark-mail-draft-edit.md.

Comment on lines +16 to +17
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix bold markdown formatting.

Line 17 ends with ** but there's no opening ** at the start of line 16.

📝 Proposed fix
-编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
+**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
🤖 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 `@skills/lark-mail/references/lark-mail-forward.md` around lines 16 - 17, The
markdown has an unmatched closing bold marker in the sentence "编辑邮件内容前 MUST 先用
Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**" — fix
by removing the trailing "**" or by adding a matching opening "**" before the
text you intend to bold (update the line containing that sentence in
lark-mail-forward.md so bold markers are balanced).

Comment on lines +16 to +17
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix bold markdown formatting.

Line 17 ends with ** but there's no opening ** at the start of line 16.

📝 Proposed fix
-编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
+**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
🤖 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 `@skills/lark-mail/references/lark-mail-reply-all.md` around lines 16 - 17, The
markdown line containing "编辑邮件内容前 MUST 先用 Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**" has
an unmatched closing bold marker; fix it by either removing the trailing "**" or
adding a matching opening "**" before the intended bold text so the Markdown is
valid—update the sentence in lark-mail-reply-all.md accordingly to use proper
bold markers.

Comment on lines +20 to +21
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix bold markdown formatting.

Line 21 ends with ** but there's no opening ** at the start of line 20.

📝 Proposed fix
-编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
+**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
🤖 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 `@skills/lark-mail/references/lark-mail-reply.md` around lines 20 - 21, The
markdown line ending with an unmatched bold delimiter ("编辑邮件内容前 MUST 先用 Read
工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**")
has a stray closing **; fix by either removing the trailing ** or adding a
matching opening ** before the intended bolded text so the bold markup is
balanced (edit the sentence text fragment shown to ensure matching **
delimiters).

Comment on lines +15 to +16
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix bold markdown formatting.

Line 16 ends with ** but there's no opening ** at the start of line 15, resulting in malformed bold text.

📝 Proposed fix
-编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
+**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
**编辑邮件内容前 MUST 先用 Read 工具读取 [references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**
🤖 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 `@skills/lark-mail/references/lark-mail-send.md` around lines 15 - 16, The line
"编辑邮件内容前 MUST 先用 Read 工具读取
[references/lark-mail-html.md](references/lark-mail-html.md),其中包含邮件书写规范**" has a
stray closing bold marker (**); fix the malformed bold by either removing the
trailing "**" or by adding a matching opening "**" before the text you intend to
bold so the markdown becomes balanced—update the sentence in the
lark-mail-send.md content accordingly.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 11, 2026

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.

❌ xulong3370
❌ bubbmon233
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/mail PR touches the mail domain size/XL Architecture-level or global-impact change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants