* Revert "fix(mail): clarify that file path flags only accept relative paths (#141)"
This reverts commit 1ffe870dc8.
* Revert "feat(mail): auto-resolve local image paths in draft body HTML (#81) (#139)"
This reverts commit 70c72a2c02.
* Reapply "fix(mail): clarify that file path flags only accept relative paths (#141)"
This reverts commit d465e085b1.
* feat: add TestGenerateShortcutsJSON for registry shortcut export
Add a test that exports all shortcuts as JSON when SHORTCUTS_OUTPUT
env var is set, enabling the registry repo to extract shortcut
metadata without depending on a dump-shortcuts CLI command.
* feat(mail): auto-resolve local image paths in draft body HTML (#81)
Allow <img src="./local/path.png" /> in set_body/set_reply_body HTML.
Local file paths are automatically resolved into inline MIME parts with
generated CIDs, eliminating the need to manually pair add_inline with
set_body. Removing or replacing an <img> tag in the body automatically
cleans up or replaces the corresponding MIME inline part.
- Add postProcessInlineImages to unify resolve, validate, and orphan
cleanup into a single post-processing step
- Extract loadAndAttachInline shared helper to deduplicate addInline
and resolveLocalImgSrc logic
- Cache resolved paths so the same file is only attached once
- Use whitelist URI scheme detection instead of blacklist
- Remove dead validateInlineCIDAfterApply and
validateOrphanedInlineCIDAfterApply functions
Closes#81
* fix(mail): harden inline image CID handling
1. Fix imgSrcRegexp to skip attribute names like data-src/x-src that
contain "src" as a suffix — only match the real src attribute.
2. Sanitize cidFromFileName to replace whitespace with hyphens,
producing RFC-safe CID tokens (e.g. "my logo.png" → "my-logo").
3. Add CID validation in newInlinePart to reject spaces, tabs, angle
brackets, and parentheses — fail fast instead of silently producing
broken inline images in the sent email.
* refactor(mail): use UUID for auto-generated inline CIDs
Replace filename-derived CID generation (cidFromFileName + uniqueCID)
with UUID-based generation. UUIDs contain only [0-9a-f-] characters,
eliminating all RFC compliance risks from special characters, Unicode,
or filename collisions. Same-file deduplication via pathToCID cache
is preserved — multiple <img> tags referencing the same file still
share one MIME part and one CID.
* fix(mail): avoid panic in generateCID by using uuid.NewRandom
uuid.New() calls Must(NewRandom()) which panics if the random source
fails. Replace with uuid.NewRandom() and propagate the error through
resolveLocalImgSrc, so the CLI returns a clear error instead of
crashing in extreme environments.
* fix(mail): restore quote block hint in set_reply_body template description
The auto-resolve PR accidentally dropped "the quote block is
re-appended automatically" from the set_reply_body shape description.
Restore it alongside the new local-path support note.
* fix(mail): add orphan invariant comment and expand regex test coverage
- Add comment in postProcessInlineImages explaining that partially
attached inline parts on error are cleaned up by the next Apply.
- Add regex test cases: single-quoted src, multiple spaces before src,
and newline before src.
* fix(mail): use consistent inline predicate and safer HTML part lookup
1. removeOrphanedInlineParts: change condition from
ContentDisposition=="inline" && ContentID!="" to
isInlinePart(child) && ContentID!="", matching the predicate used
elsewhere — parts with only a ContentID (no Content-Disposition)
are now correctly cleaned up.
2. postProcessInlineImages: use findPrimaryBodyPart instead of
findPart(snapshot.Body, PrimaryHTMLPartID) to avoid stale PartID
after ops restructure the MIME tree.
* fix(mail): revert orphan cleanup to ContentDisposition check to protect HTML body
The previous change (d3d1982) broadened the orphan cleanup predicate to
isInlinePart(), which treats any part with a ContentID as inline. This
deletes the primary HTML body when it carries a Content-ID header
(valid in multipart/related), even on metadata-only edits like
set_subject.
Revert to the original ContentDisposition=="inline" && ContentID!=""
condition — only parts explicitly marked as inline attachments are
candidates for orphan removal. Add regression test covering
multipart/related with a Content-ID-bearing HTML body.
Add non-blocking update check that queries the npm registry for the
latest @larksuite/cli version. Results are cached locally (24h TTL)
to avoid repeated network requests.
When a newer version is detected, a `_notice.update` field is injected
into all JSON output envelopes (success, error, and shortcut responses),
enabling AI agents and scripts to surface upgrade prompts.
Key changes:
- New `internal/update` package: registry fetch, semver compare, cache
- Async check in root command (cache-first, then background refresh)
- `_notice` field added to Envelope/ErrorEnvelope structs
- `PrintJson` injects notice into map-based envelopes with "ok" key
- `doctor` command gains cli_version and cli_update checks
- Suppressed for CI, DEV builds, shell completion, and git-describe versions
* fix: remove sensitive send scope from reply and forward shortcuts
Remove mail:user_mailbox.message:send from the required scopes of
+reply, +reply-all, and +forward shortcuts. This scope is sensitive
and may not be granted, while these shortcuts default to saving
drafts and do not strictly require it.
* fix: validate send scope dynamically when --confirm-send is set
Add validateConfirmSendScope() to check mail:user_mailbox.message:send
in the Validate phase when --confirm-send is used, preventing the
"draft created but send failed" scenario. Add regression tests for
+reply, +reply-all, and +forward.