Skip to content

[harness:01KP342QM8XZZT86SCJJGGK50Y-4] Mail CLI 支持定时发送 — CLI 技术方案#452

Open
infeng wants to merge 2 commits intomainfrom
harness/01KP342QM8XZZT86SCJJGGK50Y
Open

[harness:01KP342QM8XZZT86SCJJGGK50Y-4] Mail CLI 支持定时发送 — CLI 技术方案#452
infeng wants to merge 2 commits intomainfrom
harness/01KP342QM8XZZT86SCJJGGK50Y

Conversation

@infeng
Copy link
Copy Markdown
Collaborator

@infeng infeng commented Apr 13, 2026

Generated by the harness-coding skill.

  • Task ID: 01KP342QM8XZZT86SCJJGGK50Y-4
  • Branch: harness/01KP342QM8XZZT86SCJJGGK50Y
  • Target: main

Sprints

ID Title Status Commit
S2 CLI: add --send-time flag to send/reply/reply-all/forward + new cancel-scheduled-send shortcut passed d68c522

Source specs

  • /tmp/harness-agent-dev/repos/01KP342QM8XZZT86SCJJGGK50Y/01KP342QM8XZZT86SCJJGGK50Y-4/input/tech-design.md

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

Summary by CodeRabbit

  • New Features

    • Added email scheduling via --send-time for send, forward, reply, and reply-all; outputs include scheduled status and send_time when used
    • Added a cancel-scheduled-send command with helpful tips and example cancel invocation
    • Shows warnings when scheduling is specified without confirm-send
  • Behavior / Validation

    • Enforces a minimum 5-minute lead time for scheduled sends
    • Displays human-readable scheduled time summaries
  • Tests

    • Added tests covering scheduling parsing/validation, formatting, and cancel behavior

…ancel-scheduled-send shortcut

Add scheduled send support to the Mail CLI:

- New shortcuts/mail/scheduled_send.go with parseAndValidateSendTime (RFC 3339
  parsing, min 5-minute lead time, UTC default) and formatScheduledTimeHuman
- New shortcuts/mail/scheduled_send_test.go with comprehensive time parsing tests
- Modified +send, +reply, +reply-all, +forward shortcuts to accept --send-time
  flag with validation, scheduled send via SendWithBody, and status/hint output
- New +cancel-scheduled-send shortcut with --message-id (required) and
  --user-mailbox-id (default: me) flags
- New shortcuts/mail/mail_cancel_scheduled_send_test.go with success, error,
  missing-id, and custom-mailbox test cases
- Added SendWithBody to draft/service.go for passing send_time in request body
- Registered MailCancelScheduledSend in shortcuts.go
@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 Apr 13, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a2326388-ed46-4c3a-8e51-2cf1dc1bd398

📥 Commits

Reviewing files that changed from the base of the PR and between d68c522 and 150b713.

📒 Files selected for processing (2)
  • shortcuts/mail/scheduled_send.go
  • shortcuts/mail/scheduled_send_test.go
✅ Files skipped from review due to trivial changes (2)
  • shortcuts/mail/scheduled_send_test.go
  • shortcuts/mail/scheduled_send.go

📝 Walkthrough

Walkthrough

Adds scheduled send support across mail shortcuts: a new Draft API helper SendWithBody, a +cancel-scheduled-send shortcut, --send-time flags for send/forward/reply/reply-all with parsing/validation and output changes, plus scheduling utilities and tests.

Changes

Cohort / File(s) Summary
Draft Service Enhancement
shortcuts/mail/draft/service.go
Added SendWithBody(runtime, mailboxID, draftID, body) which posts to the draft send endpoint using an optional request body; falls back to Send when body is empty.
Cancel Scheduled Send
shortcuts/mail/mail_cancel_scheduled_send.go, shortcuts/mail/mail_cancel_scheduled_send_test.go
New MailCancelScheduledSend shortcut implementing +cancel-scheduled-send with validation, dry-run preview, execution calling the mail API POST cancel path, and tests for success, missing flag, API error, and custom mailbox.
Compose Shortcuts Enhancement
shortcuts/mail/mail_send.go, shortcuts/mail/mail_forward.go, shortcuts/mail/mail_reply.go, shortcuts/mail/mail_reply_all.go
Added --send-time flag (RFC3339) to compose commands; parsing/validation, warnings when --confirm-send is omitted, and conditional use of SendWithBody to include send_time; outputs include status: "scheduled" and send_time when applicable, plus cancel tips.
Scheduled Send Utilities & Tests
shortcuts/mail/scheduled_send.go, shortcuts/mail/scheduled_send_test.go
Introduced parseAndValidateSendTime (enforces 5-minute lead, supports RFC3339 and timezone-less input) and formatScheduledTimeHuman; comprehensive tests for parsing, validation, and formatting.
Registry Update
shortcuts/mail/shortcuts.go
Registered MailCancelScheduledSend in the returned shortcuts slice.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as CLI
    participant Draft as Draft Service
    participant API as Mail API

    User->>CLI: run +send / +reply ... --send-time "2026-04-15T14:30:00Z" --confirm-send
    CLI->>CLI: parseAndValidateSendTime(send-time) (RFC3339 / tz-less -> UTC, ensure >= 5m)
    CLI->>Draft: SendWithBody(runtime, mailboxID, draftID, { "send_time": "<unix_ts>" })
    activate Draft
    Draft->>API: POST /vX/.../drafts/{draftID}/send with JSON body
    activate API
    API-->>Draft: { message_id, thread_id, ... , status: "scheduled" }
    deactivate API
    Draft-->>CLI: response map
    CLI-->>User: print output (message_id, thread_id, status/send_time tip)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • chanthuang
  • kongenpei

Poem

🐰 A rabbit's note on scheduled mail:
I tuck messages safe for later light,
Five minutes wait then off they flight,
Tip to cancel—hop back in time,
Soft thump, the inbox keeps its rhyme ✉️

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is auto-generated by a harness tool and lacks key sections required by the template: no summary, changes list, test plan details, or related issues. Add a comprehensive description following the template: include a 1-3 sentence summary of the scheduled-send feature, list main changes, describe test verification, and document related issues.
Docstring Coverage ⚠️ Warning Docstring coverage is 19.05% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is in Chinese and contains a task ID prefix and technical design reference, but does not clearly convey the main changes in English-speaking context. Consider using an English title that clearly describes the feature, such as 'Add scheduled send support to Mail CLI with --send-time flag and cancel-scheduled-send command'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch harness/01KP342QM8XZZT86SCJJGGK50Y

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 13, 2026

Greptile Summary

This PR adds scheduled email sending via a new --send-time flag across +send, +reply, +reply-all, and +forward, and introduces a +cancel-scheduled-send shortcut. The implementation is consistent across all four compose commands.

  • The +cancel-scheduled-send shortcut declares mail:user_mailbox.message:send as its scope, but every other write/modify shortcut in this package uses mail:user_mailbox.message:modify. If the Lark API requires modify (not send) for the cancel endpoint, users who hold modify but not send will be denied at runtime.
  • parseAndValidateSendTime returns the Unix timestamp as a Go string, which JSON-serializes as \"1744599600\" rather than the number 1744599600. If the API expects an integer, every scheduled-send request will silently fail.

Confidence Score: 4/5

Merge after verifying the cancel scope and the send_time JSON type against the Lark API spec — both could cause silent runtime failures.

Two concerns remain: the cancel shortcut uses the send scope instead of the modify scope used by all other write operations (could block legitimate users at runtime), and the Unix timestamp is serialized as a JSON string rather than a number (could silently break every scheduled-send request if the API expects an integer). Neither can be verified from code alone.

shortcuts/mail/mail_cancel_scheduled_send.go (scope), shortcuts/mail/scheduled_send.go (send_time JSON type)

Important Files Changed

Filename Overview
shortcuts/mail/mail_cancel_scheduled_send.go New cancel shortcut; scope is mail:user_mailbox.message:send but every other modification shortcut uses mail:user_mailbox.message:modify, making this inconsistent and potentially broken for users without the send permission
shortcuts/mail/scheduled_send.go New utility file for send-time parsing/validation; returns Unix timestamp as a string (potential JSON type mismatch with API); formatScheduledTimeHuman is unused in production code (addressed in prior review thread)
shortcuts/mail/mail_send.go Added --send-time flag with validation, scheduled body construction, and output; outData["send_time"] still uses raw input string (addressed in prior thread)
shortcuts/mail/mail_reply.go Added --send-time support with consistent validate/execute pattern; same raw-string output issue as mail_send.go (addressed in prior thread)
shortcuts/mail/mail_reply_all.go Added --send-time support following the same pattern as mail_reply.go
shortcuts/mail/mail_forward.go Added --send-time support and validate/execute path consistent with reply commands
shortcuts/mail/draft/service.go Added SendWithBody that correctly falls back to Send when body is nil/empty
shortcuts/mail/scheduled_send_test.go Good test coverage for parseAndValidateSendTime and formatScheduledTimeHuman; tests for past time, too-soon time, invalid format, and timezone-free inputs
shortcuts/mail/mail_cancel_scheduled_send_test.go Tests cover success, missing flag, API error, and custom mailbox ID scenarios
shortcuts/mail/shortcuts.go Correctly registers the new MailCancelScheduledSend shortcut

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI
    participant Validate
    participant Execute
    participant DraftAPI
    participant SendAPI
    participant CancelAPI

    User->>CLI: lark-cli mail +send --send-time T --confirm-send
    CLI->>Validate: parseAndValidateSendTime(T)
    Validate-->>CLI: ok / validation error

    CLI->>Execute: run
    Execute->>DraftAPI: POST /drafts (create draft)
    DraftAPI-->>Execute: draft_id

    alt send-time provided
        Execute->>Execute: parseAndValidateSendTime(T) → unix_ts string
        Execute->>SendAPI: POST /drafts/{id}/send {send_time: unix_ts}
        SendAPI-->>Execute: message_id
        Execute-->>User: {status: scheduled, send_time: raw_input_str}
        Note over Execute,User: tip: lark-cli mail +cancel-scheduled-send --message-id ...
    else immediate send
        Execute->>SendAPI: POST /drafts/{id}/send
        SendAPI-->>Execute: message_id
        Execute-->>User: {message_id, thread_id}
    end

    User->>CLI: lark-cli mail +cancel-scheduled-send --message-id M
    CLI->>CancelAPI: POST /messages/{M}/cancel_scheduled_send
    CancelAPI-->>CLI: ok
    CLI-->>User: {status: cancelled, restored_as_draft: true}
Loading

Reviews (2): Last reviewed commit: "fix: return Unix timestamp instead of RF..." | Re-trigger Greptile

Comment on lines +178 to +181
if sendTimeStr != "" {
outData["status"] = "scheduled"
outData["send_time"] = sendTimeStr
fmt.Fprintf(runtime.IO().ErrOut,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Normalized send time not reflected in output

outData["send_time"] is set to the raw sendTimeStr from the user, not the validatedTime returned by parseAndValidateSendTime. Because validatedTime is declared inside the inner if block, it goes out of scope before the output is built. For timezone-free inputs like "2026-04-14T09:00:00", the API receives "2026-04-14T09:00:00Z" (UTC-normalized), but the output field shows the ambiguous original string — users who omit a timezone offset may believe the email is scheduled in their local time when it is not.

The same pattern appears in mail_reply.go (line 216), mail_reply_all.go, and mail_forward.go.

Fix: hoist validatedTime to an outer scope so it can be used when building outData:

var sendBody map[string]interface{}
var validatedSendTime string
if sendTimeStr != "" {
    var timeErr error
    validatedSendTime, timeErr = parseAndValidateSendTime(sendTimeStr)
    if timeErr != nil {
        return timeErr
    }
    sendBody = map[string]interface{}{
        "send_time": validatedSendTime,
    }
}
// ...
if sendTimeStr != "" {
    outData["status"] = "scheduled"
    outData["send_time"] = validatedSendTime   // normalized, not raw user input

Comment on lines +49 to +65
func formatScheduledTimeHuman(sendTime string) string {
t, err := time.Parse(time.RFC3339, sendTime)
if err != nil {
return sendTime
}
dur := time.Until(t)
var relative string
switch {
case dur < time.Hour:
relative = fmt.Sprintf("in %d minutes", int(dur.Minutes()))
case dur < 24*time.Hour:
relative = fmt.Sprintf("in %d hours", int(dur.Hours()))
default:
relative = fmt.Sprintf("in %d days", int(dur.Hours()/24))
}
return fmt.Sprintf("%s (%s, %s)", sendTime, t.Format("Mon"), relative)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 formatScheduledTimeHuman is dead code

This function is defined and unit-tested but never called from any production code path. None of the four --send-time send commands invoke it; the output just echoes sendTimeStr directly. Either wire it into the output (e.g. as a human-readable send_time_display field) or remove it and the corresponding tests to keep the package clean.

Comment on lines +58 to +64
_, err := runtime.CallAPI("POST", path, nil, nil)
if err != nil {
return output.ErrWithHint(output.ExitAPI, "api_error",
fmt.Sprintf("Failed to cancel scheduled send for message %s", messageID),
"Ensure the message ID is correct and the email has not already been sent.",
)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Original API error discarded

When runtime.CallAPI returns an error, the original err is silently dropped and replaced with a generic hint. Other shortcuts in this package wrap the underlying error with fmt.Errorf("...: %w", err), which preserves the diagnostic message for debugging. Consider wrapping err here so that the actual API error code/message is still surfaced:

Suggested change
_, err := runtime.CallAPI("POST", path, nil, nil)
if err != nil {
return output.ErrWithHint(output.ExitAPI, "api_error",
fmt.Sprintf("Failed to cancel scheduled send for message %s", messageID),
"Ensure the message ID is correct and the email has not already been sent.",
)
}
_, err := runtime.CallAPI("POST", path, nil, nil)
if err != nil {
return output.ErrWithHint(output.ExitAPI, "api_error",
fmt.Sprintf("Failed to cancel scheduled send for message %s: %v", messageID, err),
"Ensure the message ID is correct and the email has not already been sent.",
)
}

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 13, 2026

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#harness/01KP342QM8XZZT86SCJJGGK50Y -y -g

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: 2

🧹 Nitpick comments (1)
shortcuts/mail/mail_cancel_scheduled_send.go (1)

33-56: Reuse mailboxPath so dry-run and execute can’t drift.

These two blocks duplicate the mailbox defaulting and escaped URL template. The package already centralizes segment escaping in mailboxPath (shortcuts/mail/helpers.go), so a small helper here would keep the dry-run path and the real API call aligned.

♻️ Consolidate the path construction
 import (
 	"context"
 	"fmt"
-	"net/url"
 
 	"github.com/larksuite/cli/internal/output"
 	"github.com/larksuite/cli/shortcuts/common"
 )
 
+func cancelScheduledSendPath(userMailboxID, messageID string) string {
+	if userMailboxID == "" {
+		userMailboxID = "me"
+	}
+	return mailboxPath(userMailboxID, "messages", messageID, "cancel_scheduled_send")
+}
+
 var MailCancelScheduledSend = common.Shortcut{
 	...
 	DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
 		messageID := runtime.Str("message-id")
-		userMailboxID := runtime.Str("user-mailbox-id")
-		if userMailboxID == "" {
-			userMailboxID = "me"
-		}
 		return common.NewDryRunAPI().
 			Desc("Cancel scheduled send — message will be restored as draft").
-			POST(fmt.Sprintf("/open-apis/mail/v1/user_mailboxes/%s/messages/%s/cancel_scheduled_send",
-				url.PathEscape(userMailboxID),
-				url.PathEscape(messageID),
-			))
+			POST(cancelScheduledSendPath(runtime.Str("user-mailbox-id"), messageID))
 	},
 	Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
 		messageID := runtime.Str("message-id")
 		userMailboxID := runtime.Str("user-mailbox-id")
-		if userMailboxID == "" {
-			userMailboxID = "me"
-		}
-
-		path := fmt.Sprintf("/open-apis/mail/v1/user_mailboxes/%s/messages/%s/cancel_scheduled_send",
-			url.PathEscape(userMailboxID),
-			url.PathEscape(messageID),
-		)
+		path := cancelScheduledSendPath(userMailboxID, messageID)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/mail/mail_cancel_scheduled_send.go` around lines 33 - 56, DryRun
and Execute duplicate mailbox defaulting and escaped URL construction; replace
the duplicated fmt.Sprintf/url.PathEscape logic by calling the shared helper
mailboxPath to build the endpoint so both blocks stay in sync. In both DryRun
and Execute (functions named DryRun and Execute), compute userMailboxID as
before, then call mailboxPath(userMailboxID, "messages", messageID,
"cancel_scheduled_send") (or the existing mailboxPath signature used elsewhere)
and use its return value for the DryRun POST path and the Execute path variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@shortcuts/mail/mail_cancel_scheduled_send.go`:
- Around line 72-74: The current fmt.Fprintf call that writes the tip to
runtime.IO().ErrOut uses the wrong flag (--id) and omits mailbox context; update
the fmt.Fprintf invocation (the one that calls sanitizeForTerminal(messageID))
to use --draft-id and include the mailbox selector by passing
sanitizeForTerminal(userMailboxID) and adding the --mailbox (or --from) flag so
the hint reads like: use lark-cli mail +draft-edit --draft-id <messageID>
--mailbox <userMailboxID>.

In `@shortcuts/mail/scheduled_send_test.go`:
- Around line 36-64: Update the two tests
(TestParseAndValidateSendTime_ValidWithTimezone and
TestParseAndValidateSendTime_WithoutTimezoneDefaultsToUTC) to assert the
returned instant rather than just string shape: call
parseAndValidateSendTime(timeStr), parse the returned result with
time.Parse(time.RFC3339, result) into a time.Time (resultTime) and compare it to
the expected instant derived from your original future variable (for the
timezone test compare instants accounting for the FixedZone offset, e.g.
expected := future.In(loc).UTC(); for the no-timezone test expect UTC), using
time equality or a small-tolerance Unix timestamp comparison to avoid flakiness;
additionally assert that the no-timezone case has UTC offset (+00:00) by
checking resultTime.UTC() equals resultTime or by verifying
resultTime.Location() / Offset corresponds to UTC.

---

Nitpick comments:
In `@shortcuts/mail/mail_cancel_scheduled_send.go`:
- Around line 33-56: DryRun and Execute duplicate mailbox defaulting and escaped
URL construction; replace the duplicated fmt.Sprintf/url.PathEscape logic by
calling the shared helper mailboxPath to build the endpoint so both blocks stay
in sync. In both DryRun and Execute (functions named DryRun and Execute),
compute userMailboxID as before, then call mailboxPath(userMailboxID,
"messages", messageID, "cancel_scheduled_send") (or the existing mailboxPath
signature used elsewhere) and use its return value for the DryRun POST path and
the Execute path variable.
🪄 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: 628b8b0a-bcd3-4a6b-abf9-ead5eaf5aa8f

📥 Commits

Reviewing files that changed from the base of the PR and between 88fd3bd and d68c522.

📒 Files selected for processing (10)
  • shortcuts/mail/draft/service.go
  • shortcuts/mail/mail_cancel_scheduled_send.go
  • shortcuts/mail/mail_cancel_scheduled_send_test.go
  • shortcuts/mail/mail_forward.go
  • shortcuts/mail/mail_reply.go
  • shortcuts/mail/mail_reply_all.go
  • shortcuts/mail/mail_send.go
  • shortcuts/mail/scheduled_send.go
  • shortcuts/mail/scheduled_send_test.go
  • shortcuts/mail/shortcuts.go

Comment on lines +72 to +74
fmt.Fprintf(runtime.IO().ErrOut,
"tip: the message has been restored as a draft. Use lark-cli mail +draft-edit --id %s to edit.\n",
sanitizeForTerminal(messageID))
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

draft_edit_file="$(rg -n --type=go 'Command:\s*"\+draft-edit"' | cut -d: -f1 | head -n1)"
if [ -z "${draft_edit_file}" ]; then
  echo "Could not find the +draft-edit shortcut definition" >&2
  exit 1
fi

echo "=== +draft-edit shortcut definition: ${draft_edit_file} ==="
sed -n '1,240p' "${draft_edit_file}"

echo
echo "=== mailbox-related flags/path usage in ${draft_edit_file} ==="
rg -n 'Name:\s*"user-mailbox-id"|mailboxPath\(|runtime\.Str\("user-mailbox-id"\)' "${draft_edit_file}"

Repository: larksuite/cli

Length of output: 12017


🏁 Script executed:

cat -n shortcuts/mail/mail_cancel_scheduled_send.go | sed -n '50,90p'

Repository: larksuite/cli

Length of output: 1093


🏁 Script executed:

rg -n "messageID|mailboxID|resolveComposeMailboxID" shortcuts/mail/mail_cancel_scheduled_send.go | head -20

Repository: larksuite/cli

Length of output: 368


🏁 Script executed:

# Search for similar hint patterns in mail shortcuts that might include mailbox context
rg -n "Use lark-cli mail" shortcuts/mail/ -A 1 -B 1

Repository: larksuite/cli

Length of output: 372


🏁 Script executed:

cat -n shortcuts/mail/mail_cancel_scheduled_send.go | sed -n '35,65p'

Repository: larksuite/cli

Length of output: 1335


🏁 Script executed:

rg -n "MailCancelScheduledSend\s*=" shortcuts/mail/mail_cancel_scheduled_send.go -A 30 | head -50

Repository: larksuite/cli

Length of output: 1378


🏁 Script executed:

rg -n 'Name:\s*"draft-id"|Name:\s*"mailbox"|Name:\s*"from"' shortcuts/mail/mail_draft_edit.go | head -10

Repository: larksuite/cli

Length of output: 548


Include mailbox context in the draft-edit hint and use the correct flag name.

Line 73 has two issues. The hint uses --id, but the correct flag is --draft-id. More critically, the hint omits the mailbox selector. When a user cancels scheduled send from a custom mailbox (e.g., --user-mailbox-id custom@example.com), the restored draft is placed in that mailbox. The hint should include the mailbox context so the follow-up command targets the correct mailbox; otherwise, +draft-edit defaults to me and the user won't find the restored draft.

The hint should include the mailbox context (captured from userMailboxID) using --mailbox or --from:

Suggested fix
fmt.Fprintf(runtime.IO().ErrOut,
	"tip: the message has been restored as a draft. Use lark-cli mail +draft-edit --draft-id %s --mailbox %s to edit.\n",
	sanitizeForTerminal(messageID), sanitizeForTerminal(userMailboxID))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/mail/mail_cancel_scheduled_send.go` around lines 72 - 74, The
current fmt.Fprintf call that writes the tip to runtime.IO().ErrOut uses the
wrong flag (--id) and omits mailbox context; update the fmt.Fprintf invocation
(the one that calls sanitizeForTerminal(messageID)) to use --draft-id and
include the mailbox selector by passing sanitizeForTerminal(userMailboxID) and
adding the --mailbox (or --from) flag so the hint reads like: use lark-cli mail
+draft-edit --draft-id <messageID> --mailbox <userMailboxID>.

…endTime

The backend API expects send_time as a Unix seconds timestamp (i64),
not an RFC 3339 string. Update parseAndValidateSendTime to return
fmt.Sprintf("%d", t.Unix()) and adjust unit tests accordingly.

sprint: S1
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.

1 participant