← back to khang859__google-suite-cli

Function bodies 106 total

All specs Real LLM only Function bodies
cmd.init function · go · L58-L63 (6 LOC)
cmd/accounts.go
func init() {
	accountsCmd.AddCommand(accountsListCmd)
	accountsCmd.AddCommand(accountsSwitchCmd)
	accountsCmd.AddCommand(accountsRemoveCmd)
	rootCmd.AddCommand(accountsCmd)
}
cmd.runAccountsList function · go · L65-L106 (42 LOC)
cmd/accounts.go
func runAccountsList(cmd *cobra.Command, args []string) error {
	store, err := auth.LoadAccountStore()
	if err != nil {
		return fmt.Errorf("failed to load account store: %w", err)
	}

	accounts := store.List()
	if len(accounts) == 0 {
		if GetOutputFormat() == "json" {
			return outputJSON([]struct{}{})
		}
		fmt.Println("No authenticated accounts. Run 'gsuite login' to add one.")
		return nil
	}

	if GetOutputFormat() == "json" {
		type accountItem struct {
			Email   string `json:"email"`
			AddedAt string `json:"added_at"`
			Active  bool   `json:"active"`
		}
		var results []accountItem
		for _, entry := range accounts {
			results = append(results, accountItem{
				Email:   entry.Email,
				AddedAt: entry.AddedAt.Format("2006-01-02"),
				Active:  strings.EqualFold(entry.Email, store.Active),
			})
		}
		return outputJSON(results)
	}

	for _, entry := range accounts {
		marker := " "
		if strings.EqualFold(entry.Email, store.Active) {
			marker = "*"
		}
		fmt.Printf("%s %s  (add
cmd.runAccountsSwitch function · go · L108-L126 (19 LOC)
cmd/accounts.go
func runAccountsSwitch(cmd *cobra.Command, args []string) error {
	email := args[0]

	store, err := auth.LoadAccountStore()
	if err != nil {
		return fmt.Errorf("failed to load account store: %w", err)
	}

	if err := store.SetActive(email); err != nil {
		return err
	}

	if err := store.Save(); err != nil {
		return fmt.Errorf("failed to save account store: %w", err)
	}

	fmt.Printf("Switched to %s\n", email)
	return nil
}
cmd.runAccountsRemove function · go · L128-L150 (23 LOC)
cmd/accounts.go
func runAccountsRemove(cmd *cobra.Command, args []string) error {
	email := args[0]

	store, err := auth.LoadAccountStore()
	if err != nil {
		return fmt.Errorf("failed to load account store: %w", err)
	}

	if err := store.RemoveAccount(email); err != nil {
		return err
	}

	if err := store.Save(); err != nil {
		return fmt.Errorf("failed to save account store: %w", err)
	}

	if err := auth.DeleteTokenFor(email); err != nil {
		return fmt.Errorf("failed to remove token: %w", err)
	}

	fmt.Printf("Removed account %s\n", email)
	return nil
}
cmd.init function · go · L168-L249 (82 LOC)
cmd/calendar.go
func init() {
	rootCmd.AddCommand(calendarCmd)
	calendarCmd.AddCommand(calendarListCmd)
	calendarCmd.AddCommand(calendarGetCmd)
	calendarCmd.AddCommand(calendarTodayCmd)
	calendarCmd.AddCommand(calendarWeekCmd)
	calendarCmd.AddCommand(calendarCalendarsCmd)
	calendarCmd.AddCommand(calendarCreateCmd)
	calendarCmd.AddCommand(calendarUpdateCmd)
	calendarCmd.AddCommand(calendarDeleteCmd)
	calendarCmd.AddCommand(calendarRespondCmd)

	// List flags
	calendarListCmd.Flags().StringVar(&calendarID, "calendar-id", "primary", "Calendar ID")
	calendarListCmd.Flags().Int64VarP(&calendarMaxResults, "max-results", "n", 25, "Maximum number of events")
	calendarListCmd.Flags().StringVar(&calendarAfter, "after", "", "Show events after this time")
	calendarListCmd.Flags().StringVar(&calendarBefore, "before", "", "Show events before this time")
	calendarListCmd.Flags().StringVarP(&calendarQuery, "query", "q", "", "Search query")
	calendarListCmd.Flags().BoolVar(&calendarSingleEvents, "single-events", true,
cmd.resolveTimezone function · go · L251-L260 (10 LOC)
cmd/calendar.go
func resolveTimezone() (*time.Location, error) {
	if calendarTimezone != "" {
		loc, err := time.LoadLocation(calendarTimezone)
		if err != nil {
			return nil, fmt.Errorf("invalid timezone %q: %w", calendarTimezone, err)
		}
		return loc, nil
	}
	return time.Now().Location(), nil
}
cmd.listCalendarEvents function · go · L262-L346 (85 LOC)
cmd/calendar.go
func listCalendarEvents(cmd *cobra.Command, calID string, timeMin, timeMax time.Time, maxResults int64, query string, singleEvents bool, orderBy string, tz *time.Location, showDeleted bool) error {
	ctx := context.Background()

	service, err := auth.NewCalendarService(ctx, GetAccountEmail())
	if err != nil {
		return auth.HandleCalendarError(err, "authentication failed")
	}

	call := service.Events.List(calID).
		TimeMin(timeMin.Format(time.RFC3339)).
		TimeMax(timeMax.Format(time.RFC3339)).
		SingleEvents(singleEvents).
		ShowDeleted(showDeleted).
		Fields("items(id,summary,start,end,location,status,recurringEventId),nextPageToken")

	if orderBy != "" {
		call = call.OrderBy(orderBy)
	}
	if query != "" {
		call = call.Q(query)
	}
	if calendarTimezone != "" {
		call = call.TimeZone(calendarTimezone)
	}

	call.MaxResults(min(maxResults, 250))

	var allEvents []*calendar.Event
	err = call.Pages(ctx, func(page *calendar.Events) error {
		allEvents = append(allEvents, page.Items...)
		if i
Repobility analyzer · published findings · https://repobility.com
cmd.printEventTable function · go · L348-L362 (15 LOC)
cmd/calendar.go
func printEventTable(events []*calendar.Event, tz *time.Location) {
	fmt.Printf("%-12s %-20s %s\n", "DATE", "TIME", "SUMMARY")
	fmt.Printf("%-12s %-20s %s\n", "----", "----", "-------")

	for _, ev := range events {
		date, timeRange := formatEventTableRow(ev, tz)
		summary := ev.Summary
		if ev.RecurringEventId != "" {
			summary += " (recurring)"
		}
		fmt.Printf("%-12s %-20s %s\n", date, timeRange, summary)
	}

	fmt.Printf("\n[%d event(s)]\n", len(events))
}
cmd.formatEventTableRow function · go · L364-L401 (38 LOC)
cmd/calendar.go
func formatEventTableRow(ev *calendar.Event, tz *time.Location) (string, string) {
	if ev.Start == nil {
		return "", ""
	}

	if ev.Start.Date != "" {
		t, err := time.Parse("2006-01-02", ev.Start.Date)
		if err != nil {
			return ev.Start.Date, "all day"
		}
		return t.Format("2006-01-02"), "all day"
	}

	if ev.Start.DateTime != "" {
		startT, err := time.Parse(time.RFC3339, ev.Start.DateTime)
		if err != nil {
			return "", ev.Start.DateTime
		}
		startT = startT.In(tz)
		date := startT.Format("2006-01-02")
		startStr := startT.Format("03:04 PM")

		endStr := ""
		if ev.End != nil && ev.End.DateTime != "" {
			endT, err := time.Parse(time.RFC3339, ev.End.DateTime)
			if err == nil {
				endStr = endT.In(tz).Format("03:04 PM")
			}
		}

		if endStr != "" {
			return date, startStr + " - " + endStr
		}
		return date, startStr
	}

	return "", ""
}
cmd.runCalendarList function · go · L403-L430 (28 LOC)
cmd/calendar.go
func runCalendarList(cmd *cobra.Command, args []string) error {
	tz, err := resolveTimezone()
	if err != nil {
		return err
	}

	now := time.Now().In(tz)

	timeMin := now
	if calendarAfter != "" {
		t, err := parseDateTime(calendarAfter, tz, now)
		if err != nil {
			return fmt.Errorf("invalid --after value: %w", err)
		}
		timeMin = t
	}

	timeMax := now.AddDate(0, 0, 30)
	if calendarBefore != "" {
		t, err := parseDateTime(calendarBefore, tz, now)
		if err != nil {
			return fmt.Errorf("invalid --before value: %w", err)
		}
		timeMax = t
	}

	return listCalendarEvents(cmd, calendarID, timeMin, timeMax, calendarMaxResults, calendarQuery, calendarSingleEvents, calendarOrderBy, tz, calendarShowDeleted)
}
cmd.runCalendarGet function · go · L432-L565 (134 LOC)
cmd/calendar.go
func runCalendarGet(cmd *cobra.Command, args []string) error {
	eventID := args[0]

	tz, err := resolveTimezone()
	if err != nil {
		return err
	}

	ctx := context.Background()
	service, err := auth.NewCalendarService(ctx, GetAccountEmail())
	if err != nil {
		return auth.HandleCalendarError(err, "authentication failed")
	}

	ev, err := service.Events.Get(calendarID, eventID).Do()
	if err != nil {
		return auth.HandleCalendarError(err, "failed to get event")
	}

	if GetOutputFormat() == "json" {
		type attendeeItem struct {
			Email          string `json:"email"`
			DisplayName    string `json:"display_name"`
			ResponseStatus string `json:"response_status"`
			Organizer      bool   `json:"organizer"`
			Self           bool   `json:"self"`
		}
		type eventDetail struct {
			ID               string         `json:"id"`
			Summary          string         `json:"summary"`
			Start            string         `json:"start"`
			End              string         `json:"end"`
			Status           s
cmd.runCalendarToday function · go · L567-L578 (12 LOC)
cmd/calendar.go
func runCalendarToday(cmd *cobra.Command, args []string) error {
	tz, err := resolveTimezone()
	if err != nil {
		return err
	}

	now := time.Now().In(tz)
	dayStart := startOfDay(now, tz)
	dayEnd := dayStart.AddDate(0, 0, 1)

	return listCalendarEvents(cmd, calendarID, dayStart, dayEnd, calendarMaxResults, "", true, "startTime", tz, false)
}
cmd.runCalendarWeek function · go · L580-L593 (14 LOC)
cmd/calendar.go
func runCalendarWeek(cmd *cobra.Command, args []string) error {
	tz, err := resolveTimezone()
	if err != nil {
		return err
	}

	now := time.Now().In(tz)
	// Find Monday of the current week
	daysFromMonday := (int(now.Weekday()) - int(time.Monday) + 7) % 7
	weekStart := startOfDay(now.AddDate(0, 0, -daysFromMonday), tz)
	weekEnd := weekStart.AddDate(0, 0, 7)

	return listCalendarEvents(cmd, calendarID, weekStart, weekEnd, calendarMaxResults, "", true, "startTime", tz, false)
}
cmd.runCalendarCalendars function · go · L595-L654 (60 LOC)
cmd/calendar.go
func runCalendarCalendars(cmd *cobra.Command, args []string) error {
	ctx := context.Background()

	service, err := auth.NewCalendarService(ctx, GetAccountEmail())
	if err != nil {
		return auth.HandleCalendarError(err, "authentication failed")
	}

	resp, err := service.CalendarList.List().
		MaxResults(calendarMaxResults).
		Do()
	if err != nil {
		return auth.HandleCalendarError(err, "failed to list calendars")
	}

	if GetOutputFormat() == "json" {
		type calendarItem struct {
			ID         string `json:"id"`
			Summary    string `json:"summary"`
			AccessRole string `json:"access_role"`
			Primary    bool   `json:"primary"`
			Timezone   string `json:"timezone"`
		}

		if len(resp.Items) == 0 {
			return outputJSON([]struct{}{})
		}

		items := make([]calendarItem, len(resp.Items))
		for i, cal := range resp.Items {
			items[i] = calendarItem{
				ID:         cal.Id,
				Summary:    cal.Summary,
				AccessRole: cal.AccessRole,
				Primary:    cal.Primary,
				Timezone:   cal.TimeZon
cmd.parseDateTime function · go · L24-L55 (32 LOC)
cmd/calendar_time.go
func parseDateTime(input string, loc *time.Location, now time.Time) (time.Time, error) {
	input = strings.TrimSpace(input)
	if input == "" {
		return time.Time{}, fmt.Errorf("empty datetime input; accepted formats: RFC3339, 2006-01-02, 2006-01-02 15:04, 2006-01-02T15:04:05, 15:04, today, tomorrow, monday-sunday, +Nd")
	}

	if t, ok := parseRelative(input, loc, now); ok {
		return t, nil
	}

	if t, err := time.Parse(time.RFC3339, input); err == nil {
		return t, nil
	}

	formats := []string{
		"2006-01-02",
		"2006-01-02 15:04",
		"2006-01-02T15:04:05",
	}
	for _, f := range formats {
		if t, err := time.ParseInLocation(f, input, loc); err == nil {
			return t, nil
		}
	}

	// Time-only: anchor to today
	if t, err := time.ParseInLocation("15:04", input, loc); err == nil {
		return time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), 0, 0, loc), nil
	}

	return time.Time{}, fmt.Errorf("cannot parse %q; accepted formats: RFC3339, 2006-01-02, 2006-01-02 15:04, 2006-01-02T15:
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
cmd.parseRelative function · go · L57-L80 (24 LOC)
cmd/calendar_time.go
func parseRelative(input string, loc *time.Location, now time.Time) (time.Time, bool) {
	lower := strings.ToLower(strings.TrimSpace(input))

	switch lower {
	case "today":
		return startOfDay(now, loc), true
	case "tomorrow":
		return startOfDay(now.AddDate(0, 0, 1), loc), true
	}

	if wd, ok := dayNames[lower]; ok {
		return nextWeekday(now.In(loc), wd), true
	}

	if m := relDaysRegexp.FindStringSubmatch(lower); m != nil {
		n := 0
		for _, c := range m[1] {
			n = n*10 + int(c-'0')
		}
		return startOfDay(now.AddDate(0, 0, n), loc), true
	}

	return time.Time{}, false
}
cmd.parseDuration function · go · L82-L91 (10 LOC)
cmd/calendar_time.go
func parseDuration(input string) (time.Duration, error) {
	d, err := time.ParseDuration(input)
	if err != nil {
		return 0, fmt.Errorf("invalid duration %q: %w", input, err)
	}
	if d <= 0 {
		return 0, fmt.Errorf("duration must be positive, got %s", d)
	}
	return d, nil
}
cmd.buildEventDateTime function · go · L93-L104 (12 LOC)
cmd/calendar_time.go
func buildEventDateTime(t time.Time, allDay bool, tz string) *calendar.EventDateTime {
	edt := &calendar.EventDateTime{}
	if allDay {
		edt.Date = t.Format("2006-01-02")
	} else {
		edt.DateTime = t.Format(time.RFC3339)
	}
	if tz != "" {
		edt.TimeZone = tz
	}
	return edt
}
cmd.formatEventTime function · go · L106-L125 (20 LOC)
cmd/calendar_time.go
func formatEventTime(edt *calendar.EventDateTime, displayTz *time.Location) string {
	if edt == nil {
		return ""
	}
	if edt.Date != "" {
		t, err := time.Parse("2006-01-02", edt.Date)
		if err != nil {
			return edt.Date
		}
		return t.Format("Mon Jan 02, 2006 (all day)")
	}
	if edt.DateTime != "" {
		t, err := time.Parse(time.RFC3339, edt.DateTime)
		if err != nil {
			return edt.DateTime
		}
		return t.In(displayTz).Format("Mon Jan 02, 2006 03:04 PM MST")
	}
	return ""
}
cmd.nextWeekday function · go · L131-L137 (7 LOC)
cmd/calendar_time.go
func nextWeekday(from time.Time, target time.Weekday) time.Time {
	days := int(target) - int(from.Weekday())
	if days <= 0 {
		days += 7
	}
	return startOfDay(from.AddDate(0, 0, days), from.Location())
}
cmd.init function · go · L16-L21 (6 LOC)
cmd/calendar_write.go
func init() {
	calendarCreateCmd.RunE = runCalendarCreate
	calendarUpdateCmd.RunE = runCalendarUpdate
	calendarDeleteCmd.RunE = runCalendarDelete
	calendarRespondCmd.RunE = runCalendarRespond
}
cmd.runCalendarCreate function · go · L23-L119 (97 LOC)
cmd/calendar_write.go
func runCalendarCreate(cmd *cobra.Command, args []string) error {
	if err := validateCalendarCreateFlags(calendarStart, calendarEnd, calendarDuration, calendarAllDay); err != nil {
		return err
	}

	tz, err := resolveTimezone()
	if err != nil {
		return err
	}

	now := time.Now().In(tz)
	startTime, err := parseDateTime(calendarStart, tz, now)
	if err != nil {
		return fmt.Errorf("invalid --start value: %w", err)
	}

	var endTime time.Time
	switch {
	case calendarEnd != "":
		endTime, err = parseDateTime(calendarEnd, tz, now)
		if err != nil {
			return fmt.Errorf("invalid --end value: %w", err)
		}
	case calendarDuration != "":
		d, err := parseDuration(calendarDuration)
		if err != nil {
			return err
		}
		endTime = startTime.Add(d)
	case calendarAllDay:
		endTime = startTime.AddDate(0, 0, 1)
	default:
		endTime = startTime.Add(time.Hour)
	}

	event := &calendar.Event{
		Summary:     calendarSummary,
		Description: calendarDescription,
		Location:    calendarLocation,
		Start:       
cmd.runCalendarUpdate function · go · L121-L248 (128 LOC)
cmd/calendar_write.go
func runCalendarUpdate(cmd *cobra.Command, args []string) error {
	eventID := args[0]

	tz, err := resolveTimezone()
	if err != nil {
		return err
	}

	ctx := context.Background()
	service, err := auth.NewCalendarService(ctx, GetAccountEmail())
	if err != nil {
		return auth.HandleCalendarError(err, "authentication failed")
	}

	event, err := service.Events.Get(calendarID, eventID).Do()
	if err != nil {
		return auth.HandleCalendarError(err, "failed to get event")
	}

	// For recurring events with --recurring-scope all, operate on the parent
	if calendarRecurringScope == "all" && event.RecurringEventId != "" {
		eventID = event.RecurringEventId
		event, err = service.Events.Get(calendarID, eventID).Do()
		if err != nil {
			return auth.HandleCalendarError(err, "failed to get recurring event")
		}
	}

	now := time.Now().In(tz)

	if cmd.Flags().Changed("summary") {
		event.Summary = calendarSummary
	}

	if cmd.Flags().Changed("start") {
		startTime, err := parseDateTime(calendarStart, tz
Open data scored by Repobility · https://repobility.com
cmd.runCalendarDelete function · go · L250-L292 (43 LOC)
cmd/calendar_write.go
func runCalendarDelete(cmd *cobra.Command, args []string) error {
	eventID := args[0]

	if calendarRecurringScope == "all" && !calendarYes {
		return fmt.Errorf("this will delete ALL instances of this recurring event. Use --yes to confirm, or --recurring-scope this to delete only this instance")
	}

	ctx := context.Background()
	service, err := auth.NewCalendarService(ctx, GetAccountEmail())
	if err != nil {
		return auth.HandleCalendarError(err, "authentication failed")
	}

	// For recurring events with --recurring-scope all, operate on the parent
	if calendarRecurringScope == "all" {
		event, err := service.Events.Get(calendarID, eventID).Do()
		if err != nil {
			return auth.HandleCalendarError(err, "failed to get event")
		}
		if event.RecurringEventId != "" {
			eventID = event.RecurringEventId
		}
	}

	err = service.Events.Delete(calendarID, eventID).SendUpdates(calendarSendUpdates).Do()
	if err != nil {
		return auth.HandleCalendarError(err, "failed to delete event")
	}

	if Get
cmd.runCalendarRespond function · go · L294-L357 (64 LOC)
cmd/calendar_write.go
func runCalendarRespond(cmd *cobra.Command, args []string) error {
	eventID := args[0]

	validStatuses := map[string]bool{
		"accepted":  true,
		"declined":  true,
		"tentative": true,
	}
	if !validStatuses[calendarStatus] {
		return fmt.Errorf("invalid --status %q: must be one of accepted, declined, tentative", calendarStatus)
	}

	ctx := context.Background()
	service, err := auth.NewCalendarService(ctx, GetAccountEmail())
	if err != nil {
		return auth.HandleCalendarError(err, "authentication failed")
	}

	event, err := service.Events.Get(calendarID, eventID).Do()
	if err != nil {
		return auth.HandleCalendarError(err, "failed to get event")
	}

	var selfAttendee *calendar.EventAttendee
	for _, a := range event.Attendees {
		if a.Self {
			selfAttendee = a
			break
		}
	}
	if selfAttendee == nil {
		return fmt.Errorf("you are not listed as an attendee of this event")
	}

	selfAttendee.ResponseStatus = calendarStatus
	if calendarComment != "" {
		selfAttendee.Comment = calendarCommen
cmd.validateCalendarCreateFlags function · go · L359-L367 (9 LOC)
cmd/calendar_write.go
func validateCalendarCreateFlags(start, end, duration string, allDay bool) error {
	if end != "" && duration != "" {
		return fmt.Errorf("--end and --duration are mutually exclusive")
	}
	if allDay && duration != "" {
		return fmt.Errorf("--all-day and --duration cannot be combined")
	}
	return nil
}
cmd.validateAttendeeEmails function · go · L369-L391 (23 LOC)
cmd/calendar_write.go
func validateAttendeeEmails(csv string) ([]string, error) {
	parts := strings.Split(csv, ",")
	emails := make([]string, 0, len(parts))

	for _, part := range parts {
		email := strings.TrimSpace(part)
		if email == "" {
			continue
		}

		addr, err := mail.ParseAddress(email)
		if err != nil {
			// Try wrapping with angle brackets for bare emails
			addr, err = mail.ParseAddress("<" + email + ">")
			if err != nil {
				return nil, fmt.Errorf("invalid email address %q: %w", email, err)
			}
		}
		emails = append(emails, addr.Address)
	}

	return emails, nil
}
cmd.init function · go · L143-L171 (29 LOC)
cmd/drafts.go
func init() {
	rootCmd.AddCommand(draftsCmd)
	draftsCmd.AddCommand(draftsListCmd)
	draftsCmd.AddCommand(draftsGetCmd)
	draftsCmd.AddCommand(draftsCreateCmd)
	draftsCmd.AddCommand(draftsUpdateCmd)
	draftsCmd.AddCommand(draftsSendCmd)
	draftsCmd.AddCommand(draftsDeleteCmd)

	// draftsListCmd flags
	draftsListCmd.Flags().Int64VarP(&draftsMaxResults, "max-results", "n", 10, "Maximum number of drafts to return (max 500)")

	// draftsCreateCmd flags
	draftsCreateCmd.Flags().StringVarP(&draftTo, "to", "t", "", "Recipient email address (required)")
	draftsCreateCmd.Flags().StringVarP(&draftSubject, "subject", "s", "", "Email subject (required)")
	draftsCreateCmd.Flags().StringVarP(&draftBody, "body", "b", "", "Plain text body content (required)")
	draftsCreateCmd.Flags().StringVar(&draftCc, "cc", "", "CC recipients (comma-separated)")
	draftsCreateCmd.Flags().StringVar(&draftBcc, "bcc", "", "BCC recipients (comma-separated)")
	draftsCreateCmd.MarkFlagRequired("to")
	draftsCreateCmd.MarkFlagReq
cmd.runDraftsList function · go · L173-L291 (119 LOC)
cmd/drafts.go
func runDraftsList(cmd *cobra.Command, args []string) error {
	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Build the list request
	listCall := service.Users.Drafts.List("me")

	// Apply max results (cap at 500)
	if draftsMaxResults > 500 {
		draftsMaxResults = 500
	}
	listCall.MaxResults(draftsMaxResults)

	// Execute the request
	resp, err := listCall.Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// Check if no drafts found
	if len(resp.Drafts) == 0 {
		if GetOutputFormat() == "json" {
			return outputJSON([]struct{}{})
		}
		fmt.Println("No drafts found.")
		return nil
	}

	// JSON output mode
	if GetOutputFormat() == "json" {
		type draftListItem struct {
			DraftID   string `json:"draft_id"`
			MessageID string `json:"message_id"`
			Subject   string `json:"subject"`
			Snippet   string `json:"snippet"`
		}
		var results []draftL
cmd.runDraftsGet function · go · L293-L367 (75 LOC)
cmd/drafts.go
func runDraftsGet(cmd *cobra.Command, args []string) error {
	draftID := args[0]

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Get the draft with full format
	draft, err := service.Users.Drafts.Get("me", draftID).Format("full").Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	if draft.Message == nil || draft.Message.Payload == nil {
		return fmt.Errorf("draft not found: %s", draftID)
	}

	// Extract headers
	var to, subject, date string
	for _, header := range draft.Message.Payload.Headers {
		switch header.Name {
		case "To":
			to = header.Value
		case "Subject":
			subject = header.Value
		case "Date":
			date = header.Value
		}
	}

	// Extract body content
	body := extractDraftBody(draft.Message)

	// JSON output mode
	if GetOutputFormat() == "json" {
		type draftGetResult struct {
			DraftID string `json:"draft_id"`
			To      stri
cmd.extractDraftBody function · go · L371-L383 (13 LOC)
cmd/drafts.go
func extractDraftBody(msg *gmail.Message) string {
	if msg.Payload == nil {
		return ""
	}

	// Check if the payload itself has body data
	if msg.Payload.MimeType == "text/plain" && msg.Payload.Body != nil && msg.Payload.Body.Data != "" {
		return decodeDraftBase64URL(msg.Payload.Body.Data)
	}

	// Search through parts
	return findDraftPlainTextPart(msg.Payload.Parts)
}
Repobility — same analyzer, your code, free for public repos · /scan/
cmd.findDraftPlainTextPart function · go · L386-L399 (14 LOC)
cmd/drafts.go
func findDraftPlainTextPart(parts []*gmail.MessagePart) string {
	for _, part := range parts {
		if part.MimeType == "text/plain" && part.Body != nil && part.Body.Data != "" {
			return decodeDraftBase64URL(part.Body.Data)
		}
		// Recurse into nested parts (for multipart messages)
		if len(part.Parts) > 0 {
			if content := findDraftPlainTextPart(part.Parts); content != "" {
				return content
			}
		}
	}
	return ""
}
cmd.decodeDraftBase64URL function · go · L402-L412 (11 LOC)
cmd/drafts.go
func decodeDraftBase64URL(encoded string) string {
	decoded, err := base64.URLEncoding.DecodeString(encoded)
	if err != nil {
		// Try with padding
		decoded, err = base64.RawURLEncoding.DecodeString(encoded)
		if err != nil {
			return ""
		}
	}
	return string(decoded)
}
cmd.runDraftsCreate function · go · L414-L458 (45 LOC)
cmd/drafts.go
func runDraftsCreate(cmd *cobra.Command, args []string) error {
	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Build RFC 2822 formatted message
	message := buildRFC2822Message(draftTo, draftSubject, draftBody, draftCc, draftBcc)

	// Base64url encode the message
	encodedMessage := base64.URLEncoding.EncodeToString([]byte(message))

	// Create the draft
	draft := &gmail.Draft{
		Message: &gmail.Message{
			Raw: encodedMessage,
		},
	}

	created, err := service.Users.Drafts.Create("me", draft).Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// JSON output mode
	if GetOutputFormat() == "json" {
		type draftCreateResult struct {
			DraftID   string `json:"draft_id"`
			MessageID string `json:"message_id"`
		}
		msgID := ""
		if created.Message != nil {
			msgID = created.Message.Id
		}
		return outputJSON(draftCreateResult{
			DraftID:   cre
cmd.runDraftsUpdate function · go · L460-L558 (99 LOC)
cmd/drafts.go
func runDraftsUpdate(cmd *cobra.Command, args []string) error {
	draftID := args[0]

	if draftTo == "" && draftSubject == "" && draftBody == "" && draftCc == "" && draftBcc == "" {
		return fmt.Errorf("at least one of --to, --subject, --body, --cc, or --bcc is required")
	}

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Get existing draft to preserve unmodified fields
	existing, err := service.Users.Drafts.Get("me", draftID).Format("full").Do()
	if err != nil {
		return fmt.Errorf("draft not found: %s", draftID)
	}

	// Extract existing values from headers
	var existingTo, existingSubject, existingCc, existingBcc string
	if existing.Message != nil && existing.Message.Payload != nil {
		for _, header := range existing.Message.Payload.Headers {
			switch header.Name {
			case "To":
				existingTo = header.Value
			case "Subject":
				existingSubject = header.Value
cmd.runDraftsSend function · go · L560-L592 (33 LOC)
cmd/drafts.go
func runDraftsSend(cmd *cobra.Command, args []string) error {
	draftID := args[0]

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Send the draft
	draft := &gmail.Draft{
		Id: draftID,
	}

	sent, err := service.Users.Drafts.Send("me", draft).Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// JSON output mode
	if GetOutputFormat() == "json" {
		type draftSendResult struct {
			MessageID string `json:"message_id"`
		}
		return outputJSON(draftSendResult{
			MessageID: sent.Id,
		})
	}

	fmt.Printf("Draft sent as message: %s\n", sent.Id)
	return nil
}
cmd.runDraftsDelete function · go · L594-L624 (31 LOC)
cmd/drafts.go
func runDraftsDelete(cmd *cobra.Command, args []string) error {
	draftID := args[0]

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Delete the draft
	err = service.Users.Drafts.Delete("me", draftID).Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// JSON output mode
	if GetOutputFormat() == "json" {
		type draftDeleteResult struct {
			DraftID string `json:"draft_id"`
			Deleted bool   `json:"deleted"`
		}
		return outputJSON(draftDeleteResult{
			DraftID: draftID,
			Deleted: true,
		})
	}

	fmt.Printf("Draft deleted: %s\n", draftID)
	return nil
}
cmd.buildRFC2822Message function · go · L627-L644 (18 LOC)
cmd/drafts.go
func buildRFC2822Message(to, subject, body, cc, bcc string) string {
	var msg string

	msg += fmt.Sprintf("To: %s\r\n", to)
	if cc != "" {
		msg += fmt.Sprintf("Cc: %s\r\n", cc)
	}
	if bcc != "" {
		msg += fmt.Sprintf("Bcc: %s\r\n", bcc)
	}
	msg += fmt.Sprintf("Subject: %s\r\n", subject)
	msg += "MIME-Version: 1.0\r\n"
	msg += "Content-Type: text/plain; charset=\"UTF-8\"\r\n"
	msg += "\r\n"
	msg += body

	return msg
}
cmd.runInstallSkill function · go · L40-L49 (10 LOC)
cmd/install_skill.go
func runInstallSkill(cmd *cobra.Command, args []string) error {
	client, _ := cmd.Flags().GetString("client")
	skillsDir, ok := clientSkillDirs[client]
	if !ok {
		return fmt.Errorf("unknown client %q (supported: claude, openclaw-workspace)", client)
	}
	targetDir := filepath.Join(skillsDir, "gsuite-manager")

	return installSkillFiles(SkillFS, "skills/gsuite-manager", targetDir)
}
Repobility analyzer · published findings · https://repobility.com
cmd.installSkillFiles function · go · L51-L80 (30 LOC)
cmd/install_skill.go
func installSkillFiles(source fs.FS, embeddedRoot, targetDir string) error {
	sub, err := fs.Sub(source, embeddedRoot)
	if err != nil {
		return fmt.Errorf("reading embedded skill files: %w", err)
	}

	return fs.WalkDir(sub, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}

		dest := filepath.Join(targetDir, path)

		if d.IsDir() {
			return os.MkdirAll(dest, 0o755)
		}

		data, err := fs.ReadFile(sub, path)
		if err != nil {
			return fmt.Errorf("reading %s: %w", path, err)
		}

		if err := os.WriteFile(dest, data, 0o644); err != nil {
			return fmt.Errorf("writing %s: %w", dest, err)
		}

		fmt.Println("  wrote", dest)
		return nil
	})
}
cmd.init function · go · L125-L142 (18 LOC)
cmd/labels.go
func init() {
	rootCmd.AddCommand(labelsCmd)
	labelsCmd.AddCommand(labelsListCmd)
	labelsCmd.AddCommand(labelsCreateCmd)
	labelsCmd.AddCommand(labelsUpdateCmd)
	labelsCmd.AddCommand(labelsDeleteCmd)

	// labelsCreateCmd flags
	labelsCreateCmd.Flags().StringVarP(&labelName, "name", "n", "", "Name for the new label (required)")
	labelsCreateCmd.Flags().StringVar(&labelListVisibility, "label-list-visibility", "", "Label list visibility (labelShow, labelShowIfUnread, labelHide)")
	labelsCreateCmd.Flags().StringVar(&messageListVisibility, "message-list-visibility", "", "Message list visibility (show, hide)")
	labelsCreateCmd.MarkFlagRequired("name")

	// labelsUpdateCmd flags (reuses the same flag variables)
	labelsUpdateCmd.Flags().StringVarP(&labelName, "name", "n", "", "New name for the label")
	labelsUpdateCmd.Flags().StringVar(&labelListVisibility, "label-list-visibility", "", "Label list visibility (labelShow, labelShowIfUnread, labelHide)")
	labelsUpdateCmd.Flags().StringVar(&message
cmd.runLabelsList function · go · L144-L214 (71 LOC)
cmd/labels.go
func runLabelsList(cmd *cobra.Command, args []string) error {
	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// List labels
	resp, err := service.Users.Labels.List("me").Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// Separate system and user labels
	var systemLabels, userLabels []*gmail.Label
	for _, label := range resp.Labels {
		if label.Type == "system" {
			systemLabels = append(systemLabels, label)
		} else {
			userLabels = append(userLabels, label)
		}
	}

	// Sort each group alphabetically by name
	sort.Slice(systemLabels, func(i, j int) bool {
		return systemLabels[i].Name < systemLabels[j].Name
	})
	sort.Slice(userLabels, func(i, j int) bool {
		return userLabels[i].Name < userLabels[j].Name
	})

	// JSON output mode
	if GetOutputFormat() == "json" {
		type labelItem struct {
			ID   string `json:"id"`
			Name string `json:"na
cmd.runLabelsCreate function · go · L216-L265 (50 LOC)
cmd/labels.go
func runLabelsCreate(cmd *cobra.Command, args []string) error {
	if labelName == "" {
		return fmt.Errorf("--name flag is required")
	}

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Build the label object
	label := &gmail.Label{
		Name: labelName,
	}

	// Set optional visibility settings
	if labelListVisibility != "" {
		label.LabelListVisibility = labelListVisibility
	}
	if messageListVisibility != "" {
		label.MessageListVisibility = messageListVisibility
	}

	// Create the label
	created, err := service.Users.Labels.Create("me", label).Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// JSON output mode
	if GetOutputFormat() == "json" {
		type labelCreateResult struct {
			ID                    string `json:"id"`
			Name                  string `json:"name"`
			LabelListVisibility   string `json:"label_list_visibility"`
			MessageLis
cmd.runLabelsUpdate function · go · L267-L335 (69 LOC)
cmd/labels.go
func runLabelsUpdate(cmd *cobra.Command, args []string) error {
	labelID := args[0]

	// Check if it's a system label
	if systemLabelIDs[labelID] || strings.HasPrefix(labelID, "CATEGORY_") {
		return fmt.Errorf("cannot modify system label: %s", labelID)
	}

	if labelName == "" && labelListVisibility == "" && messageListVisibility == "" {
		return fmt.Errorf("at least one of --name, --label-list-visibility, or --message-list-visibility is required")
	}

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// First, get the existing label to check if it exists
	existing, err := service.Users.Labels.Get("me", labelID).Do()
	if err != nil {
		if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "Not Found") {
			return fmt.Errorf("label not found: %s", labelID)
		}
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// Check if it's a system label by type
cmd.runLabelsDelete function · go · L337-L386 (50 LOC)
cmd/labels.go
func runLabelsDelete(cmd *cobra.Command, args []string) error {
	labelID := args[0]

	// Check if it's a system label
	if systemLabelIDs[labelID] || strings.HasPrefix(labelID, "CATEGORY_") {
		return fmt.Errorf("cannot delete system label: %s", labelID)
	}

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// First, verify the label exists and check if it's a system label
	existing, err := service.Users.Labels.Get("me", labelID).Do()
	if err != nil {
		if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "Not Found") {
			return fmt.Errorf("label not found: %s", labelID)
		}
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// Check if it's a system label by type
	if existing.Type == "system" {
		return fmt.Errorf("cannot delete system label: %s", labelID)
	}

	// Delete the label
	err = service.Users.Labels.Delete("me", labelID).Do()
	if err != n
cmd.runLogin function · go · L52-L73 (22 LOC)
cmd/login.go
func runLogin(cmd *cobra.Command, args []string) error {
	credJSON, err := auth.LoadCredentials()
	if err != nil {
		return fmt.Errorf("no credentials found: %w", err)
	}

	ctx := context.Background()

	email, err := auth.Login(ctx, credJSON)
	if err != nil {
		return err
	}

	fmt.Printf("Logged in as %s\n", email)

	store, err := auth.LoadAccountStore()
	if err == nil && len(store.List()) > 1 {
		fmt.Printf("Active account set to %s. Use 'gsuite accounts list' to see all accounts.\n", email)
	}

	return nil
}
cmd.runLogout function · go · L75-L113 (39 LOC)
cmd/login.go
func runLogout(cmd *cobra.Command, args []string) error {
	store, err := auth.LoadAccountStore()
	if err != nil {
		return fmt.Errorf("failed to load account store: %w", err)
	}

	var email string
	if len(args) > 0 {
		email = args[0]
	} else {
		email, err = store.GetActive()
		if err != nil {
			fmt.Println("Not logged in")
			return nil
		}
	}

	if err := store.RemoveAccount(email); err != nil {
		return err
	}

	if err := store.Save(); err != nil {
		return fmt.Errorf("failed to save account store: %w", err)
	}

	if err := auth.DeleteTokenFor(email); err != nil {
		return fmt.Errorf("failed to remove token: %w", err)
	}

	fmt.Printf("Logged out of %s\n", email)

	if len(store.List()) > 0 {
		fmt.Printf("Active account: %s\n", store.Active)
	} else {
		fmt.Println("No remaining accounts")
	}

	return nil
}
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
cmd.init function · go · L132-L150 (19 LOC)
cmd/messages.go
func init() {
	rootCmd.AddCommand(messagesCmd)
	messagesCmd.AddCommand(messagesListCmd)
	messagesCmd.AddCommand(messagesGetCmd)
	messagesCmd.AddCommand(messagesModifyCmd)
	messagesCmd.AddCommand(messagesGetAttachmentCmd)

	// messagesListCmd flags
	messagesListCmd.Flags().Int64VarP(&maxResults, "max-results", "n", 10, "Maximum number of messages to return (max 500)")
	messagesListCmd.Flags().StringVar(&labelIDs, "label-ids", "", "Comma-separated label IDs to filter by (e.g., INBOX,UNREAD)")
	messagesListCmd.Flags().StringVarP(&query, "query", "q", "", "Gmail search query string")

	// messagesModifyCmd flags
	messagesModifyCmd.Flags().StringVar(&addLabels, "add-labels", "", "Comma-separated label IDs to add (e.g., STARRED,Label_123)")
	messagesModifyCmd.Flags().StringVar(&removeLabels, "remove-labels", "", "Comma-separated label IDs to remove (e.g., UNREAD,INBOX)")

	// messagesGetAttachmentCmd flags
	messagesGetAttachmentCmd.Flags().StringVarP(&attachmentOutput, "output", "o", "", "Ou
cmd.runMessagesList function · go · L152-L240 (89 LOC)
cmd/messages.go
func runMessagesList(cmd *cobra.Command, args []string) error {
	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Build the list request
	listCall := service.Users.Messages.List("me")

	// Apply max results (cap at 500)
	if maxResults > 500 {
		maxResults = 500
	}
	listCall.MaxResults(maxResults)

	// Apply label filter if provided
	if labelIDs != "" {
		labels := strings.Split(labelIDs, ",")
		listCall.LabelIds(labels...)
	}

	// Apply search query if provided
	if query != "" {
		listCall.Q(query)
	}

	// Execute the request
	resp, err := listCall.Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// Check if no messages found
	if len(resp.Messages) == 0 {
		if GetOutputFormat() == "json" {
			return outputJSON([]struct{}{})
		}
		fmt.Println("No messages found.")
		return nil
	}

	// JSON output mode
	if GetOutputFormat() == "json" {
		type 
cmd.runMessagesGet function · go · L242-L349 (108 LOC)
cmd/messages.go
func runMessagesGet(cmd *cobra.Command, args []string) error {
	messageID := args[0]

	ctx := context.Background()

	service, err := auth.NewGmailService(ctx, GetAccountEmail())
	if err != nil {
		return fmt.Errorf("authentication failed: %w", err)
	}

	// Get the message with full format
	msg, err := service.Users.Messages.Get("me", messageID).Format("full").Do()
	if err != nil {
		return fmt.Errorf("Gmail API error: %w", err)
	}

	// Extract headers
	var from, to, subject, date string
	for _, header := range msg.Payload.Headers {
		switch header.Name {
		case "From":
			from = header.Value
		case "To":
			to = header.Value
		case "Subject":
			subject = header.Value
		case "Date":
			date = header.Value
		}
	}

	// Extract body content
	body := extractBody(msg)
	if body == "" {
		body = msg.Snippet
	}

	// Extract attachments
	attachments := findAttachments(msg.Payload.Parts)

	// JSON output mode
	if GetOutputFormat() == "json" {
		type attachmentJSON struct {
			Filename     string
page 1 / 3next ›