Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Support for organising events/meetings and sending invitations by email.
.claude/skills/aiskillstore-extension-email-calendar-events/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-21 | ✗→✓ | ▲ Improved | 19% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 56% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 0% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -13% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 24% | 0% |
Calendar events email extension for Caffeine AI.
This skill adds support for organising events/meetings and sending iCalendar invitations by email. It provides CRUD operations for calendar events and email-based invitation delivery.
mo:caffeineai-email-calendar-events/calendarEvents.mo which cannot be modified.mo:caffeineai-email-calendar-events/calendarEvents.momodule { public type State = { var events : List.List<CalendarEvent>; var uidMap : Map.Map<Text, Nat>; }; public func add( self : State, uid : Text, summary : Text, description : Text, location : Text, startTime : Nat64, endTime : Nat64, organizer : Mailbox, attendees : [Attendee] ) : ?CalendarEvent; public func update( self : State, uid : Text, summary : ?Text, description : ?Text, location : ?Text, startTime : ?Nat64, endTime : ?Nat64, organizer : ?Mailbox, attendees : ?[Attendee] ) : ?CalendarEvent; public func addAttendees( self : State, uid : Text, attendees : [Attendee] ) : ?CalendarEvent; public func removeAttendees( self : State, uid : Text, attendees : [Text] ) : ?CalendarEvent; public func cancel(self : State, uid : Text) : ?CalendarEvent; public func delete(self : State, uid : Text); public func get(self : State, uid : Text) : ?CalendarEvent; // Iterate over all calendar events older to newer public func iter(self : State) : Iter.Iter<CalendarEvent>; // Iterate over all calendar events newer to older public func reverse(self : State) : Iter.Iter<CalendarEvent>; }
mo:caffeineai-email/emailClient.momodule { public type CalendarEvent = { uid : Text; sequence : Nat32; method : CalendarEventMethod; summary : Text; description : Text; location : Text; startTime : Nat64; endTime : Nat64; organizer : Mailbox; attendees : [Attendee]; }; public type CalendarEventMethod = { #request; #publish; #cancel; }; public type Mailbox = { email : Text; name : ?Text; }; public type Attendee = { who : Mailbox; role : CalendarEventRole; }; public type CalendarEventRole = { #chair; #required; #optional; #notParticipating; }; public type SendResult = { #ok; #err : Text; }; public func sendCalendarEvent(fromUsername : Text, event : CalendarEvent) : async SendResult; };
motoko filepath=src/backend/main.moimport Runtime "mo:core/Runtime"; import Principal "mo:core/Principal"; import Map "mo:core/Map"; import Random "mo:core/Random"; import Set "mo:core/Set"; import Iter "mo:core/Iter"; import Option "mo:core/Option"; import Text "mo:core/Text"; import AccessControl "mo:caffeineai-authorization/access-control"; import MixinAuthorization "mo:caffeineai-authorization/MixinAuthorization"; import EmailClient "mo:caffeineai-email/emailClient"; import CalendarEvents "mo:caffeineai-email-calendar-events/calendarEvents"; import Uuid "mo:caffeineai-email-calendar-events/uuid"; actor { public type UserProfile = { name : Text; email : Text; }; // Include authorization component let accessControlState = AccessControl.initState(); include MixinAuthorization(accessControlState); // Store a map of caller principal to UserProfile var userProfiles = Map.empty<Principal, UserProfile>(); // Store a set of emails for uniqueness check var emails = Set.empty<Text>(); // Store the calendar events let calendarEvents = CalendarEvents.new(); public shared ({ caller }) func registerUser(name : Text, email : Text) : async () { // Check if the user already exists if (userProfiles.containsKey(caller)) { Runtime.trap("User already registered"); }; // Check if the email is already used if (emails.contains(email)) { Runtime.trap("Email already taken"); }; // Add a user record userProfiles.add( caller, { name; email; } ); emails.add(email); }; public shared ({ caller }) func addCalendarEvent(summary : Text, description : Text, location : Text, startTimeMs : Nat64, endTimeMs : Nat64) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can add calendar events"); }; let organiser = switch (userProfiles.get(caller)) { case (?o) { o }; case (null) { Runtime.trap("Admin profile not found") }; }; let seed = await Random.blob(); let uid = Uuid.generateV4(seed); if ( calendarEvents.add( uid, summary, description, location, startTimeMs, endTimeMs, { name = ?organiser.name; email = organiser.email; }, userProfiles.values().map( func({ name; email }) { { who = { name = ?name; email }; role = #required; }; } ).toArray() ).isNull() ) { Runtime.trap("Failed to add calendar event"); }; }; public shared ({ caller }) func updateEventDetails(uid : Text, summary : ?Text, description : ?Text, location : ?Text, startTimeMs : ?Nat64, endTimeMs : ?Nat64) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can update calendar events"); }; if ( calendarEvents.update( uid, summary, description, location, startTimeMs, endTimeMs, null, null ).isNull() ) { Runtime.trap("Failed to update calendar event"); }; }; public shared ({ caller }) func addEventAttendees(uid : Text, attendees : [EmailClient.Attendee]) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can add calendar event attendees"); }; if (calendarEvents.addAttendees(uid, attendees).isNull()) { Runtime.trap("Failed to add attendees to calendar event"); }; }; public shared ({ caller }) func removeEventAttendees(uid : Text, attendees : [Text]) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can remove calendar event attendees"); }; if (calendarEvents.removeAttendees(uid, attendees).isNull()) { Runtime.trap("Failed to remove attendees from calendar event"); }; }; public shared ({ caller }) func cancelEvent(uid : Text) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can cancel calendar events"); }; if (calendarEvents.cancel(uid).isNull()) { Runtime.trap("Failed to cancel calendar event"); }; }; public shared ({ caller }) func listEvents() : async [CalendarEvents.CalendarEvent] { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can list calendar events"); }; calendarEvents.iter().toArray(); }; public shared ({ caller }) func deleteEvent(uid : Text) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can delete calendar events"); }; calendarEvents.delete(uid); }; public shared ({ caller }) func sendEventInvitation(uid : Text) : async () { if (not (AccessControl.hasPermission(accessControlState, caller, #admin))) { Runtime.trap("Unauthorized: Only admins can send calendar event invitations"); }; let event = switch (calendarEvents.get(uid)) { case (?e) { e }; case (null) { Runtime.trap("Calendar event not found") }; }; ignore await EmailClient.sendCalendarEvent( "no-reply", event ); }; };
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-21 | fail→pass | 17,415 | 6,251 | -64% | 1 | 1 | 0% | 2,909 | 3,449 | +19% | 0 | 0 | — |
case-22 | fail→pass | 12,173 | 5,357 | -56% | 1 | 1 | 0% | 2,155 | 3,357 | +56% | 0 | 0 | — |
case-01 | fail→pass | 40,506 | 28,861 | -29% | 1 | 1 | 0% | 7,690 | 7,698 | +0% | 0 | 0 | — |
case-23 | pass→pass | 7,384 | 2,923 | -60% | 1 | 1 | 0% | 1,246 | 2,825 | +127% | 0 | 0 | — |
case-02 | fail→pass | 30,839 | 15,312 | -50% | 1 | 1 | 0% | 5,401 | 4,699 | -13% | 0 | 0 | — |
case-03 | fail→pass | 21,027 | 13,755 | -35% | 1 | 1 | 0% | 3,319 | 4,124 | +24% | 0 | 0 | — |
case-04 | fail→pass | 14,421 | 8,968 | -38% | 1 | 1 | 0% | 1,593 | 2,950 | +85% | 0 | 0 | — |
case-05 | fail→pass | 20,230 | 8,169 | -60% | 1 | 1 | 0% | 2,236 | 2,927 | +31% | 0 | 0 | — |
case-06 | fail→pass | 13,697 | 9,487 | -31% | 1 | 1 | 0% | 2,241 | 3,247 | +45% | 0 | 0 | — |
case-07 | pass→pass | 17,148 | 11,331 | -34% | 1 | 1 | 0% | 2,199 | 3,283 | +49% | 0 | 0 | — |
case-08 | fail→pass | 12,225 | 7,828 | -36% | 1 | 1 | 0% | 2,050 | 2,859 | +39% | 0 | 0 | — |
case-09 | pass→pass | 19,729 | 7,762 | -61% | 1 | 1 | 0% | 3,260 | 2,813 | -14% | 0 | 0 | — |
case-10 | fail→pass | 9,279 | 1,867 | -80% | 1 | 1 | 0% | 1,497 | 2,712 | +81% | 0 | 0 | — |
case-11 | pass→pass | 4,315 | 7,033 | +63% | 1 | 1 | 0% | 671 | 2,663 | +297% | 0 | 0 | — |
case-12 | fail→pass | 14,105 | 3,495 | -75% | 1 | 1 | 0% | 1,572 | 3,029 | +93% | 0 | 0 | — |
case-13 | fail→pass | 16,967 | 8,543 | -50% | 1 | 1 | 0% | 1,971 | 2,842 | +44% | 0 | 0 | — |
case-14 | fail→pass | 14,820 | 10,055 | -32% | 1 | 1 | 0% | 2,459 | 2,994 | +22% | 0 | 0 | — |
case-15 | pass→pass | 14,443 | 1,820 | -87% | 1 | 1 | 0% | 1,428 | 2,661 | +86% | 0 | 0 | — |
case-16 | pass→pass | 4,796 | 7,729 | +61% | 1 | 1 | 0% | 741 | 2,818 | +280% | 0 | 0 | — |
case-17 | pass→pass | 12,135 | 8,144 | -33% | 1 | 1 | 0% | 2,065 | 2,917 | +41% | 0 | 0 | — |
case-18 | fail→pass | 17,309 | 7,008 | -60% | 1 | 1 | 0% | 2,039 | 2,641 | +30% | 0 | 0 | — |
case-19 | pass→pass | 15,583 | 7,596 | -51% | 1 | 1 | 0% | 1,744 | 2,848 | +63% | 0 | 0 | — |
case-20 | fail→pass | 16,476 | 4,410 | -73% | 1 | 1 | 0% | 2,992 | 3,175 | +6% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +65 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.