Skip to content

feat(calendar): implement rsvp shortcut#151

Merged
calendar-assistant merged 1 commit intomainfrom
feat/calendar-rsvp
Mar 31, 2026
Merged

feat(calendar): implement rsvp shortcut#151
calendar-assistant merged 1 commit intomainfrom
feat/calendar-rsvp

Conversation

@calendar-assistant
Copy link
Copy Markdown
Collaborator

@calendar-assistant calendar-assistant commented Mar 31, 2026

Summary

  • Add a calendar +rsvp shortcut to reply to calendar events.
  • Register the shortcut in the calendar shortcut list.
  • Add tests and calendar skill reference docs for the new RSVP flow.

Usage

Accept an event on the primary calendar:

lark-cli calendar +rsvp --event-id evt_xxx --rsvp-status accept

Decline an event:

lark-cli calendar +rsvp --event-id evt_xxx --rsvp-status decline

Mark an event as tentative:

lark-cli calendar +rsvp --event-id evt_xxx --rsvp-status tentative

Reply to an event on a specific calendar:

lark-cli calendar +rsvp --calendar-id cal_xxx --event-id evt_xxx --rsvp-status accept

Preview the API call without executing it:

lark-cli calendar +rsvp --event-id evt_xxx --rsvp-status accept --dry-run

Notes

  • Required scope: calendar:calendar.event:reply
  • You can get the target event-id from commands such as lark-cli calendar +agenda

Testing

go test -count=1 ./shortcuts/calendar/...
go build ./...

Summary by CodeRabbit

  • New Features

    • Added a new calendar "+rsvp" command to reply to event invitations with accept, decline, or tentative; supports an optional calendar selector and a dry-run preview.
  • Documentation

    • Added full reference docs with examples, flags, required scope, and usage guidance.
  • Tests

    • Added end-to-end and validation tests covering success, API failure, dry-run output, and input-safety checks.

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 31, 2026

Greptile Summary

This PR adds a +rsvp shortcut to the calendar service, letting users accept, decline, or mark themselves tentative for calendar events. The implementation follows the established shortcut pattern (flag declaration, enum enforcement, RejectDangerousChars validation, EncodePathSegment in the URL, dry-run support) and ships with four targeted tests and updated skill docs.

Key findings

  • Validate contains a redundant rsvp-status status check (lines 62-65) that can never be reached: the framework's validateEnumFlags runs first and already enforces the same constraint via the Enum field on the flag definition.
  • The strings.ToLower normalization applied in both DryRun and Execute is inconsistent with validateEnumFlags, which does a case-sensitive match against [\"accept\", \"decline\", \"tentative\"]. Mixed-case input is rejected at the enum-check stage, making the ToLower dead code.
  • DryRun reads calendar-id without strings.TrimSpace (unlike Execute), which can produce a misleading preview if the value contains surrounding whitespace.

Confidence Score: 4/5

Safe to merge; all issues are style/consistency concerns with no impact on the primary RSVP execution path.

The shortcut correctly constructs the API URL with path encoding, validates required fields, guards against dangerous characters, and is backed by four tests. The three flagged issues are all P2: redundant dead code and minor DryRun/Execute inconsistencies that do not affect runtime correctness.

shortcuts/calendar/calendar_rsvp.go — redundant Validate block and ToLower/TrimSpace inconsistencies worth cleaning up before merge.

Important Files Changed

Filename Overview
shortcuts/calendar/calendar_rsvp.go New shortcut implementing the RSVP reply flow; has a redundant status check in Validate (unreachable due to prior enum enforcement), minor DryRun TrimSpace gap, and a misleading ToLower that the framework's case-sensitive enum check makes dead code.
shortcuts/calendar/calendar_test.go Four new RSVP tests cover success, invalid status, API error, and dangerous-character injection; all expectations align with framework behaviour.
shortcuts/calendar/shortcuts.go CalendarRsvp registered in the correct alphabetical slot; count test updated to 5.
skills/lark-calendar/SKILL.md +rsvp added to both the description field and the shortcut table; wording is consistent with other entries.
skills/lark-calendar/references/lark-calendar-rsvp.md New reference doc covers all flags, example commands, and back-links; content matches the implementation.

Sequence Diagram

sequenceDiagram
    actor User
    participant CLI as lark-cli calendar +rsvp
    participant Runner as runShortcut
    participant EnumCheck as validateEnumFlags
    participant Validate as CalendarRsvp.Validate
    participant Execute as CalendarRsvp.Execute
    participant API as Lark OpenAPI

    User->>CLI: --event-id evt_xxx --rsvp-status accept
    CLI->>Runner: runShortcut()
    Runner->>EnumCheck: validate rsvp-status in {accept,decline,tentative}
    alt invalid value
        EnumCheck-->>User: FlagError invalid value
    end
    EnumCheck-->>Runner: OK
    Runner->>Validate: RejectDangerousChars, event-id not empty
    alt dangerous chars or empty event-id
        Validate-->>User: ErrValidation
    end
    Validate-->>Runner: OK
    Runner->>Execute: Execute()
    Execute->>API: POST /open-apis/calendar/v4/calendars/{calendar_id}/events/{event_id}/reply
    Note right of Execute: body: {rsvp_status: accept}
    API-->>Execute: {code:0, msg:ok}
    Execute->>User: JSON envelope {ok:true, data:{calendar_id, event_id, rsvp_status}}
Loading

Reviews (1): Last reviewed commit: "feat(calendar): implement rsvp shortcut" | Re-trigger Greptile

Comment thread shortcuts/calendar/calendar_rsvp.go Outdated
Comment thread shortcuts/calendar/calendar_rsvp.go Outdated
Comment thread shortcuts/calendar/calendar_rsvp.go Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

Added a new exported calendar shortcut CalendarRsvp implementing calendar +rsvp to reply to calendar invitations (accept/decline/tentative). Includes flag parsing/defaulting, input validation, dry-run, execution that posts RSVP to the Calendar API, tests, and documentation.

Changes

Cohort / File(s) Summary
RSVP Shortcut Implementation
shortcuts/calendar/calendar_rsvp.go
New exported CalendarRsvp shortcut with flags --calendar-id (optional, defaults to primary), --event-id (required), --rsvp-status (required: `accept
Tests
shortcuts/calendar/calendar_test.go
Added tests for success case, dry-run normalization, invalid --rsvp-status, API failure handling, and input-safety (dangerous Unicode/control characters). Updated shortcut registration test expectation from 4 to 5 shortcuts.
Registration & Docs
shortcuts/calendar/shortcuts.go, skills/lark-calendar/SKILL.md, skills/lark-calendar/references/lark-calendar-rsvp.md
Registered CalendarRsvp in shortcuts list. Updated skill metadata to include +rsvp. Added reference doc describing usage, parameters (--event-id, --rsvp-status, optional --calendar-id, --dry-run), examples, and required OAuth scope (calendar:calendar.event:reply).

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as "CLI Shortcut\n(+rsvp)"
    participant Validator as "Input Validator"
    participant API as "Lark Calendar API"
    participant Output as "Output Handler"

    User->>CLI: run `calendar +rsvp --event-id EID --rsvp-status accept [--calendar-id CID]`
    CLI->>Validator: trim inputs, check enums, reject dangerous/control chars
    alt validation fails
        Validator-->>CLI: error
        CLI-->>User: display validation error
    else validation passes
        Validator-->>CLI: validated inputs
        CLI->>CLI: default calendar-id to primary if empty
        CLI->>API: POST /open-apis/calendar/v4/calendars/:calendar_id/events/:event_id/reply
        Note right of API: Body: { "rsvp_status": "accept" }
        alt API success
            API-->>CLI: success payload
            CLI->>Output: format calendar_id, event_id, rsvp_status
            Output-->>User: display result
        else API failure
            API-->>CLI: error payload
            CLI-->>User: display API error
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related issues

Poem

🐰📅 A rabbit hops in to reply with a cheer,
“accept”, “decline”, or “tentative” — now clear.
Trims and checks every character with care,
Posts the RSVP so your calendar’s aware.
Hooray for replies and tests that are near!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing a new RSVP shortcut for the calendar service.

✏️ 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 feat/calendar-rsvp

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

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/calendar/calendar_test.go (1)

587-673: Please cover the explicit --calendar-id branch.

All new RSVP tests hit the implicit primary URL. One happy-path case with --calendar-id cal_xxx would protect the non-primary path construction that CalendarRsvp.Execute exposes and the new docs advertise.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/calendar/calendar_test.go` around lines 587 - 673, Add a test that
exercises the explicit --calendar-id branch by registering an httpmock stub for
the non-primary path and invoking CalendarRsvp with --calendar-id; e.g. create a
new test (e.g. TestRsvp_WithCalendarID) that uses cmdutil.TestFactory,
reg.Register a POST stub for
"/open-apis/calendar/v4/calendars/cal_xxx/events/evt_rsvp1/reply" returning
{code:0,msg:"ok"}, call mountAndRun(CalendarRsvp,
["+rsvp","--calendar-id","cal_xxx","--event-id","evt_rsvp1","--rsvp-status","accept","--as","bot"],
...), assert no error and that stdout contains the expected payload bits (e.g.
"event_id": "evt_rsvp1" and "rsvp_status": "accept") to confirm
CalendarRsvp.Execute builds the non-primary URL correctly.
🤖 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/calendar/calendar_rsvp.go`:
- Around line 48-55: The Validate function's loop uses
common.RejectDangerousChars but that helper allows tab/newline, so add an
explicit check for control whitespace: for the ID-like flags "calendar-id" and
"event-id" (inside the same Validate anonymous function) after trimming, detect
any '\n' or '\t' (or other control whitespace via unicode.IsControl) and return
output.ErrValidation with a clear message (e.g., "--event-id contains invalid
control characters"); keep the existing common.RejectDangerousChars call for
other dangerous chars and only apply the explicit control-character rejection to
"calendar-id" and "event-id".

In `@skills/lark-calendar/SKILL.md`:
- Line 4: The docs are inconsistent: add the missing API and scope entries for
RSVP support by inserting "events.reply" into the "### events" list (so the
events list includes events.reply alongside existing entries) and add the
corresponding permission "calendar:calendar.event:reply" to the 权限表
(scopes/permissions table) so the top-level skill doc matches the new reference
and shortcut (+rsvp) coverage; update any neighbouring descriptive text to
mention RSVP where other event operations are listed.

---

Nitpick comments:
In `@shortcuts/calendar/calendar_test.go`:
- Around line 587-673: Add a test that exercises the explicit --calendar-id
branch by registering an httpmock stub for the non-primary path and invoking
CalendarRsvp with --calendar-id; e.g. create a new test (e.g.
TestRsvp_WithCalendarID) that uses cmdutil.TestFactory, reg.Register a POST stub
for "/open-apis/calendar/v4/calendars/cal_xxx/events/evt_rsvp1/reply" returning
{code:0,msg:"ok"}, call mountAndRun(CalendarRsvp,
["+rsvp","--calendar-id","cal_xxx","--event-id","evt_rsvp1","--rsvp-status","accept","--as","bot"],
...), assert no error and that stdout contains the expected payload bits (e.g.
"event_id": "evt_rsvp1" and "rsvp_status": "accept") to confirm
CalendarRsvp.Execute builds the non-primary URL correctly.
🪄 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: 6f12535e-a1ff-4523-bba5-6aa03af59d9b

📥 Commits

Reviewing files that changed from the base of the PR and between 8fc7e12 and 0fd9eed.

📒 Files selected for processing (5)
  • shortcuts/calendar/calendar_rsvp.go
  • shortcuts/calendar/calendar_test.go
  • shortcuts/calendar/shortcuts.go
  • skills/lark-calendar/SKILL.md
  • skills/lark-calendar/references/lark-calendar-rsvp.md

Comment thread shortcuts/calendar/calendar_rsvp.go
Comment thread skills/lark-calendar/SKILL.md
hugang-lark
hugang-lark previously approved these changes Mar 31, 2026
Change-Id: I96170f024f1c8bb6f44de752961e58e5fec61644
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.

♻️ Duplicate comments (1)
shortcuts/calendar/calendar_rsvp.go (1)

49-55: ⚠️ Potential issue | 🟡 Minor

Reject tab/newline control whitespace for ID flags explicitly.

common.RejectDangerousChars still allows \t/\n, so --calendar-id and --event-id can pass with embedded control whitespace. Please add an explicit rejection for these flags before calling RejectDangerousChars.

Suggested fix
 	Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
 		for _, flag := range []string{"calendar-id", "event-id", "rsvp-status"} {
-			if val := strings.TrimSpace(runtime.Str(flag)); val != "" {
+			raw := runtime.Str(flag)
+			if val := strings.TrimSpace(raw); val != "" {
+				if (flag == "calendar-id" || flag == "event-id") && strings.ContainsAny(raw, "\t\r\n") {
+					return output.ErrValidation(fmt.Sprintf("parameter %q contains disallowed whitespace control characters", "--"+flag))
+				}
 				if err := common.RejectDangerousChars("--"+flag, val); err != nil {
 					return output.ErrValidation(err.Error())
 				}
 			}
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/calendar/calendar_rsvp.go` around lines 49 - 55, The loop over
flags currently only calls common.RejectDangerousChars which allows
tabs/newlines; for the "calendar-id" and "event-id" flags explicitly check the
trimmed value returned by runtime.Str(flag) for any tab or newline characters
(e.g., strings.ContainsAny(val, "\t\n")) and return output.ErrValidation with a
clear message (including the flag name) if found, then proceed to call
common.RejectDangerousChars as before; update the loop around runtime.Str,
common.RejectDangerousChars, and output.ErrValidation to enforce this additional
check for those two flags.
🧹 Nitpick comments (1)
shortcuts/calendar/calendar_rsvp.go (1)

30-40: Consider centralizing RSVP input normalization.

DryRun and Execute duplicate trim/default logic for the same flags. Extracting a small helper would reduce drift risk between preview and execution paths.

Also applies to: 64-70

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@shortcuts/calendar/calendar_rsvp.go` around lines 30 - 40, Duplicate
trimming/default logic for calendarId, eventId, and status in the DryRun and
Execute paths should be moved into a single helper to avoid drift; create a
function (e.g., normalizeRSVPInputs or normalizeCalendarIDAndFlags) that accepts
the runtime (or raw strings from runtime.Str) and returns trimmed calendarId
(with empty/"primary" normalized to "<primary>"), eventId, and status, then call
that helper from both DryRun (where d := common.NewDryRunAPI() is used) and
Execute to replace the duplicated code around calendarId/eventId/status (also
present in the later block around lines 64-70). Ensure the helper uses the same
runtime.Str keys ("calendar-id", "event-id", "rsvp-status") so both paths get
identical normalization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@shortcuts/calendar/calendar_rsvp.go`:
- Around line 49-55: The loop over flags currently only calls
common.RejectDangerousChars which allows tabs/newlines; for the "calendar-id"
and "event-id" flags explicitly check the trimmed value returned by
runtime.Str(flag) for any tab or newline characters (e.g.,
strings.ContainsAny(val, "\t\n")) and return output.ErrValidation with a clear
message (including the flag name) if found, then proceed to call
common.RejectDangerousChars as before; update the loop around runtime.Str,
common.RejectDangerousChars, and output.ErrValidation to enforce this additional
check for those two flags.

---

Nitpick comments:
In `@shortcuts/calendar/calendar_rsvp.go`:
- Around line 30-40: Duplicate trimming/default logic for calendarId, eventId,
and status in the DryRun and Execute paths should be moved into a single helper
to avoid drift; create a function (e.g., normalizeRSVPInputs or
normalizeCalendarIDAndFlags) that accepts the runtime (or raw strings from
runtime.Str) and returns trimmed calendarId (with empty/"primary" normalized to
"<primary>"), eventId, and status, then call that helper from both DryRun (where
d := common.NewDryRunAPI() is used) and Execute to replace the duplicated code
around calendarId/eventId/status (also present in the later block around lines
64-70). Ensure the helper uses the same runtime.Str keys ("calendar-id",
"event-id", "rsvp-status") so both paths get identical normalization.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8d0ee3f0-effe-48c1-8e37-8f77ffc12fd6

📥 Commits

Reviewing files that changed from the base of the PR and between 0fd9eed and d12c68b.

📒 Files selected for processing (5)
  • shortcuts/calendar/calendar_rsvp.go
  • shortcuts/calendar/calendar_test.go
  • shortcuts/calendar/shortcuts.go
  • skills/lark-calendar/SKILL.md
  • skills/lark-calendar/references/lark-calendar-rsvp.md
✅ Files skipped from review due to trivial changes (3)
  • shortcuts/calendar/shortcuts.go
  • skills/lark-calendar/SKILL.md
  • skills/lark-calendar/references/lark-calendar-rsvp.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • shortcuts/calendar/calendar_test.go

@calendar-assistant calendar-assistant merged commit 5da3075 into main Mar 31, 2026
7 of 8 checks passed
@calendar-assistant calendar-assistant deleted the feat/calendar-rsvp branch March 31, 2026 12:19
tuxedomm pushed a commit that referenced this pull request Apr 3, 2026
Change-Id: I96170f024f1c8bb6f44de752961e58e5fec61644
@coderabbitai coderabbitai Bot mentioned this pull request Apr 27, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants