diff --git a/CHANGELOG.md b/CHANGELOG.md index c01da45..4bb582e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added - Agent safety: add baked safety-profile builds for fail-closed agent binaries, with `agent-safe`, `readonly`, and `full` profiles, filtered help/schema output, docs, and build tooling. (#366, #239) — thanks @drewburchfield. +- Calendar: add `--with-meet` to `calendar update` for adding Google Meet conferencing to existing events. (#538) — thanks @alexisperumal. - Docs: add `docs add-tab`, `docs rename-tab`, and `docs delete-tab` for managing Google Docs tabs. (#547) — thanks @chopenhauer. - Docs: support tab-scoped Markdown append and find-replace flows. (#541) — thanks @donbowman. diff --git a/internal/cmd/calendar_create_update_test.go b/internal/cmd/calendar_create_update_test.go index 0ed13f8..11f1689 100644 --- a/internal/cmd/calendar_create_update_test.go +++ b/internal/cmd/calendar_create_update_test.go @@ -335,6 +335,56 @@ func TestCalendarUpdateCmd_RunJSON(t *testing.T) { } } +func TestCalendarUpdateCmd_WithMeet(t *testing.T) { + origNew := newCalendarService + t.Cleanup(func() { newCalendarService = origNew }) + + var ( + sawConferenceData bool + sawVersion bool + ) + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + path := strings.TrimPrefix(r.URL.Path, "/calendar/v3") + if r.Method == http.MethodPatch && path == "/calendars/cal@example.com/events/ev" { + sawVersion = r.URL.Query().Get("conferenceDataVersion") == "1" + var body calendar.Event + _ = json.NewDecoder(r.Body).Decode(&body) + sawConferenceData = body.ConferenceData != nil && + body.ConferenceData.CreateRequest != nil && + body.ConferenceData.CreateRequest.ConferenceSolutionKey != nil && + body.ConferenceData.CreateRequest.ConferenceSolutionKey.Type == "hangoutsMeet" + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]any{ + "id": "ev", + "hangoutLink": "https://meet.google.com/aaa-bbbb-ccc", + }) + return + } + http.NotFound(w, r) + })) + defer srv.Close() + + svc := newCalendarServiceFromServer(t, srv) + newCalendarService = func(context.Context, string) (*calendar.Service, error) { return svc, nil } + + ctx := newCalendarJSONOutputContext(t, os.Stdout, os.Stderr) + + cmd := &CalendarUpdateCmd{} + if err := runKong(t, cmd, []string{ + "cal@example.com", + "ev", + "--with-meet", + }, ctx, &RootFlags{Account: "a@b.com"}); err != nil { + t.Fatalf("runKong: %v", err) + } + if !sawConferenceData { + t.Fatalf("expected conferenceData create request in patch body") + } + if !sawVersion { + t.Fatalf("expected conferenceDataVersion=1 on patch request") + } +} + func TestCalendarUpdateCmd_AddAttendee(t *testing.T) { origNew := newCalendarService t.Cleanup(func() { newCalendarService = origNew }) diff --git a/internal/cmd/calendar_edit.go b/internal/cmd/calendar_edit.go index d78fda9..a7f162b 100644 --- a/internal/cmd/calendar_edit.go +++ b/internal/cmd/calendar_edit.go @@ -221,6 +221,7 @@ type CalendarUpdateCmd struct { GuestsCanInviteOthers *bool `name:"guests-can-invite" help:"Allow guests to invite others"` GuestsCanModify *bool `name:"guests-can-modify" help:"Allow guests to modify event"` GuestsCanSeeOthers *bool `name:"guests-can-see-others" help:"Allow guests to see other guests"` + WithMeet bool `name:"with-meet" help:"Create a Google Meet video conference for this event"` Scope string `name:"scope" help:"For recurring events: single, future, all" default:"all"` OriginalStartTime string `name:"original-start" help:"Original start time of instance (required for scope=single,future)"` PrivateProps []string `name:"private-prop" help:"Private extended property (key=value, can be repeated)"` @@ -296,6 +297,7 @@ func (c *CalendarUpdateCmd) Run(ctx context.Context, kctx *kong.Context, flags * "add_attendee": strings.TrimSpace(c.AddAttendee), "patch": patch, "wants_add_attendee": wantsAddAttendee, + "conference_version_1": patch.ConferenceData != nil, "supports_attachments": len(patch.Attachments) > 0, }); dryRunErr != nil { return dryRunErr @@ -393,6 +395,10 @@ func (c *CalendarUpdateCmd) buildUpdatePatch(kctx *kong.Context) (*calendar.Even changed = true } + if c.applyConferenceData(kctx, patch) { + changed = true + } + if c.applyExtendedProperties(kctx, patch) { changed = true } @@ -650,6 +656,14 @@ func (c *CalendarUpdateCmd) applyGuestOptions(kctx *kong.Context, patch *calenda return changed } +func (c *CalendarUpdateCmd) applyConferenceData(kctx *kong.Context, patch *calendar.Event) bool { + if !flagProvided(kctx, "with-meet") { + return false + } + patch.ConferenceData = buildConferenceData(true) + return true +} + func (c *CalendarUpdateCmd) applyExtendedProperties(kctx *kong.Context, patch *calendar.Event) bool { if !flagProvided(kctx, "private-prop") && !flagProvided(kctx, "shared-prop") { return false diff --git a/internal/cmd/calendar_mutation_helpers.go b/internal/cmd/calendar_mutation_helpers.go index 75947bc..2ca24b1 100644 --- a/internal/cmd/calendar_mutation_helpers.go +++ b/internal/cmd/calendar_mutation_helpers.go @@ -57,6 +57,9 @@ func (m *calendarMutationContext) patchEvent(ctx context.Context, eventID string if sendUpdates != "" { call = call.SendUpdates(sendUpdates) } + if patch.ConferenceData != nil { + call = call.ConferenceDataVersion(1) + } return call.Do() }