Skip to content

feat: append default mail signatures#1342

Open
sysuljx wants to merge 1 commit into
larksuite:mainfrom
sysuljx:feat/f81fd50
Open

feat: append default mail signatures#1342
sysuljx wants to merge 1 commit into
larksuite:mainfrom
sysuljx:feat/f81fd50

Conversation

@sysuljx

@sysuljx sysuljx commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Generated by the harness-coding skill.

  • Branch: feat/f81fd50
  • Target: main

Sprints

ID Title Status Commit
S1 lark-cli mail compose 自动追加默认签名 + --no-signature + 纯文本签名降级 passed fc24225
S2 Synthesize transport contract for larksuite/cli passed 03ea6e7

Source specs

  • tech-design.md#cli-端详细实施

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

Summary by CodeRabbit

  • New Features

    • Added --no-signature flag to draft, forward, reply, reply-all, and send commands to skip all signatures
    • Implemented automatic default signature selection based on sender email when no signature flag is provided
  • Documentation

    • Updated mail command references to clarify signature behavior, override options, and mutual exclusivity of signature flags

@coderabbitai

coderabbitai Bot commented Jun 9, 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: 6be9a35b-b789-453f-a449-0f409a3f9a78

📥 Commits

Reviewing files that changed from the base of the PR and between 03ea6e7 and fc24225.

📒 Files selected for processing (12)
  • shortcuts/mail/mail_draft_create.go
  • shortcuts/mail/mail_forward.go
  • shortcuts/mail/mail_reply.go
  • shortcuts/mail/mail_reply_all.go
  • shortcuts/mail/mail_send.go
  • shortcuts/mail/signature_compose.go
  • shortcuts/mail/signature_compose_test.go
  • skills/lark-mail/references/lark-mail-draft-create.md
  • skills/lark-mail/references/lark-mail-forward.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

📝 Walkthrough

Walkthrough

This PR adds automatic default-signature support to mail compose shortcuts by introducing a --no-signature flag and refactoring signature resolution from resolveSignature() to a new resolveComposeSignature() that auto-selects default signatures by sender email and operation kind (send vs reply). HTML signatures are converted to plaintext for text-only drafts. All five compose shortcuts (send, reply, reply-all, forward, draft-create) are updated consistently, and documentation is revised to describe the new behavior.

Changes

Default signature auto-append for mail compose

Layer / File(s) Summary
Signature compose infrastructure and utilities
shortcuts/mail/signature_compose.go, shortcuts/mail/signature_compose_test.go
New --no-signature flag, signatureResult struct, and helpers for resolving default signature IDs by sender email and kind (send vs reply). Adds regex-based HTML-to-plaintext conversion with tag/image stripping, entity unescaping, and whitespace normalization. resolveComposeSignature() honors --no-signature/--signature-id priority with warnings on auto-append failures. Validation updated to enforce --no-signature/--signature-id mutual exclusivity. Tests cover default-ID selection with sender matching, plaintext conversion, and signature appending.
Send and draft-create shortcuts
shortcuts/mail/mail_send.go, shortcuts/mail/mail_draft_create.go
Both shortcuts add noSignatureFlag to flags, replace validation with validateSignatureFlags(), compute senderEmail from --from (fallback to --mailbox), call resolveComposeSignature(..., sigKindSend), and append plain-text signatures via appendPlainTextSignature() in both explicit --plain-text and non-HTML paths.
Reply and reply-all shortcuts
shortcuts/mail/mail_reply.go, shortcuts/mail/mail_reply_all.go
Both shortcuts add noSignatureFlag to flags, replace validation with validateSignatureFlags(), resolve mailboxID earlier, compute senderEmail, call resolveComposeSignature(..., sigKindReply) for reply-specific signatures, and prepend plain-text signatures (appendPlainTextSignature() + quoted) before quoted content in non-HTML mode.
Forward shortcut
shortcuts/mail/mail_forward.go
Adds noSignatureFlag, switches to validateSignatureFlags(), resolves mailboxID earlier, derives senderEmail, calls resolveComposeSignature(..., sigKindSend), and appends plain-text signatures in non-HTML forwarding.
Documentation updates
skills/lark-mail/references/lark-mail-*.md
Updated +send, +reply, +reply-all, +forward, and +draft-create reference docs: added --no-signature parameter documentation, clarified that --signature-id overrides defaults, documented automatic default-signature append when neither flag is provided, noted HTML vs plain-text signature handling, and specified --no-signature/--signature-id mutual exclusivity.

Sequence Diagram

sequenceDiagram
  participant User as User CLI
  participant Shortcut as Compose Shortcut
  participant Validator as validateSignatureFlags
  participant Resolver as resolveComposeSignature
  participant Default as defaultSignatureIDFromResponse
  participant SigAPI as Signature API
  participant Converter as signatureToPlainText
  participant Body as Body Builder

  User->>Shortcut: --from "user@example.com" [--signature-id "sig_123" | --no-signature]
  Shortcut->>Validator: validate flags
  Validator-->>Shortcut: ✓ or ValidationError
  
  Shortcut->>Resolver: resolve signature (senderEmail, sigKind)
  alt --no-signature set
    Resolver-->>Shortcut: nil signature
  else --signature-id explicit
    Resolver->>SigAPI: fetch signature by ID
    SigAPI-->>Resolver: signature HTML + images
  else auto-select
    Resolver->>Default: find default for sender+kind
    Default-->>Resolver: signature ID or "0"
    Resolver->>SigAPI: fetch signature
    SigAPI-->>Resolver: signature HTML + images
  end
  
  alt HTML mode
    Resolver-->>Shortcut: signatureResult (HTML)
  else plaintext mode
    Resolver->>Converter: convert HTML to plaintext
    Converter-->>Resolver: plaintext signature
    Resolver-->>Shortcut: signatureResult (plaintext)
  end
  
  Shortcut->>Body: compose body with signature
  Body->>Body: appendPlainTextSignature()
  Body-->>Shortcut: final message body
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The PR follows a consistent refactoring pattern across five similar shortcuts (add flag, update validation, refactor signature resolution, append plaintext signatures), but introduces new signature resolution infrastructure in signature_compose.go that requires careful review for correctness of default-ID selection logic, HTML-to-plaintext conversion, and the resolveComposeSignature() control flow.

Possibly related issues

  • larksuite/cli#1063: The changes implement automatic default-signature append for send and reply operations, addressing the "default signature not attached to draft/reply" problem, though they do not address the separate In-Reply-To header omission mentioned in that issue.

Possibly related PRs

  • larksuite/cli#318: Both PRs update sender-email resolution in compose shortcuts to derive from --from/--mailbox parameters; the sender email computed by that PR is then passed to the main PR's resolveComposeSignature() and signature appending flow.
  • larksuite/cli#1250: Both PRs modify signature validation and error paths in shortcuts/mail/signature_compose.go; the earlier PR handled validateSignatureWithPlainText errors while this PR replaces that with validateSignatureFlags and adds the new --no-signature flag handling.

Suggested labels

domain/mail, size/M, feature

Suggested reviewers

  • infeng
  • chanthuang

Poem

🐰 Signatures now follow where you roam,
Send and reply find their home,
No flag, default signs appear,
Plain text converts without fear,
Compose shortcuts, both far and near! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is largely incomplete. It lacks the required Summary, Changes list, and Test Plan sections specified in the template. Add required sections: provide a 1-3 sentence Summary, list main Changes including signature-related updates, and document Test Plan with unit test and manual verification steps.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding support for appending default mail signatures across multiple mail shortcuts.
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 unit tests (beta)
  • Create PR with unit tests

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/mail PR touches the mail domain size/M Single-domain feat or fix with limited business impact labels Jun 9, 2026
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.66292% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.58%. Comparing base (03ea6e7) to head (fc24225).

Files with missing lines Patch % Lines
shortcuts/mail/signature_compose.go 79.36% 8 Missing and 5 partials ⚠️
shortcuts/mail/mail_draft_create.go 57.14% 1 Missing and 2 partials ⚠️
shortcuts/mail/mail_forward.go 40.00% 1 Missing and 2 partials ⚠️
shortcuts/mail/mail_reply.go 40.00% 1 Missing and 2 partials ⚠️
shortcuts/mail/mail_reply_all.go 40.00% 1 Missing and 2 partials ⚠️
shortcuts/mail/mail_send.go 50.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1342   +/-   ##
=======================================
  Coverage   71.58%   71.58%           
=======================================
  Files         689      689           
  Lines       65521    65578   +57     
=======================================
+ Hits        46901    46943   +42     
- Misses      14972    14981    +9     
- Partials     3648     3654    +6     

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

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add sysuljx/cli#feat/f81fd50 -y -g

@cnzakii cnzakii 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.

🤖 AI Review | CR 汇总 | 有风险(1 个 P2,2 个 P3)

自动追加默认签名功能整体实现清晰:nil 安全、best-effort 降级(签名查询失败仅告警不阻断发信)、测试覆盖核心转换与匹配逻辑,未发现 P0/P1 问题。

  • P2:defaultSignatureIDFromResponse 在发件地址未命中时回退到 usages[0],且 +draft-create 未用 resolveComposeSenderEmail 解析发件地址,组合下可能附加其他身份的默认签名。
  • P3:纯文本签名降级丢失超链接 URL;每次 compose 新增一次 signature.ListAll 调用。

如有疑问或认为判断不准确,欢迎直接回复讨论。

}
}
if len(resp.Usages) > 0 {
return normalizeSigID(pick(resp.Usages[0]))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 AI Review | [P2 正确性] 默认签名匹配不到发件地址时回退到 usages[0],可能附加其他身份的签名

defaultSignatureIDFromResponsesenderEmail 未命中任何 usage(或为空)时,统一回退到 resp.Usages[0] 的默认签名(本块第 80-82 行)。这条回退路径在 +draft-create 中很容易被触发:mail_draft_create.go:184-187 仅用裸 --from / --mailbox 解析发件地址,未像 +send/+reply/+forward 那样调用 resolveComposeSenderEmail 兜底到 profile 主地址。因此用户不带 --from--mailbox 默认 me 时,senderEmail 为空 → 命中此回退 → 取 usages[0]

影响:当账号存在多个发信身份(别名/共享邮箱)且 usages[0] 并非用户实际发件地址时,会把另一身份的默认签名附加到邮件正文,造成身份信息不一致;同样输入下 +send 解析出主地址精确匹配、+draft-create 却落到首条 usage,两者结果可能不同。

修复建议: 让 +draft-create 复用 resolveComposeSenderEmail(runtime) 解析发件地址(与其余 compose sibling 对齐);并考虑当 senderEmail 非空但未命中任何 usage 时返回空(不附加签名),而非静默回退到 usages[0]

如有疑问或认为判断不准确,欢迎直接回复讨论。

plainTextBlankLinesRE = regexp.MustCompile(`\n{3,}`)
)

func signatureToPlainText(renderedHTML string) string {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 AI Review | [P3 正确性] 纯文本签名降级丢失超链接 URL

signatureToPlainTextplainTextTagRE<[^>]+>)剥离所有标签,<a href="https://...">官网</a> 会被压成纯文字 官网,URL 丢失;<img> 也整体删除。对于包含网址/社交链接的签名,纯文本邮件(或纯文本降级路径)收到的签名信息量低于客户端展示。

修复建议: 非阻塞。若要与客户端纯文本签名对齐,可在剥离 <a> 前把 href 提取为 文字 (URL) 形式;否则在文档中说明纯文本签名为有损降级即可。

如有疑问或认为判断不准确,欢迎直接回复讨论。

if signatureID != "" {
return signatureID, false
}
return resolveDefaultSignatureID(runtime, mailboxID, senderEmail, kind), true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 AI Review | [P3 性能] 每次 compose 都会新增一次 signature.ListAll 调用

未显式传 --signature-id/--no-signature 时(默认路径),resolveComposeSignatureID 会调用 resolveDefaultSignatureIDsignature.ListAll,即每次 +send/+reply/+forward/+draft-create 都多一次签名列表查询;命中默认签名后还会再触发 signature.Get + send_as + 图片下载。对于从不使用签名的用户,也会在每次发信时付出一次列表查询的网络往返。

修复建议: 属功能固有成本,可接受。若关注热路径延迟,可考虑在单次进程内缓存 ListAll 结果,或在文档中提示可用 --no-signature 跳过。确认为预期即可忽略。

如有疑问或认为判断不准确,欢迎直接回复讨论。

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/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