* feat(cli): improve agent ergonomics
* fix(cli): address code review findings
- Fix nil pointer dereference in confirmDestructive when flags is nil
- Deduplicate dry-run logic by delegating to dryRunExit
- Remove deprecated net.Error.Temporary() call (dead since Go 1.18)
- Add unit tests for resolveTasklistID and resolveCalendarID
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve PR #201 conflicts and follow-ups (#201) (thanks @salmonumbrella)
* fix: resolve rebase fallout for PR #201 landing (#201) (thanks @salmonumbrella)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Add Drive upload conversion with auto detection (--convert) and explicit targets (--convert-to), preserve explicit --name values, and improve conversion behavior tests/docs for PR #240.
Co-authored-by: Daniel Weber <daniel@suno.com>
* fix(gmail): fallback to send-as list for display name
* refactor(gmail): remove dead code in primarySendAsDisplayNameFromList
The condition `primary == nil && sa.IsPrimary` inside the email-matching
block can never be true because `primary` is already unconditionally set
to `sa` when `sa.IsPrimary` is true earlier in the same loop iteration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(gmail): add --from display name fallback to list test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(auth): persist manual oauth state
* feat(cli): add remote manual auth flow
* fix(auth): enforce remote manual auth state
* fix(auth): satisfy lint for manual auth flow
* fix(auth): harden remote manual auth state cache
* chore: update changelog for remote manual auth (#187) (thanks @salmonumbrella)
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(drive): add --domain flag to share command
Allow sharing files/folders with an entire Google Workspace domain
(e.g. `gog drive share <id> --domain=example.com --role=writer`).
This creates a "domain" type permission in the Drive API, enabling
the "Anyone in <org> with the link" sharing mode.
Also updates `permissions` output to display domain names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(drive): add --to target for share (#192) (thanks @Danielkweber)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat(gmail): add timezone support for date output
Add --timezone and --local flags to gmail search and watch serve commands
to control how dates are displayed. By default uses local timezone.
Users can specify any IANA timezone (e.g., America/New_York, UTC).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(gmail): fix execute test for timezone changes
Update TestExecute_GmailSearch_JSON to use explicit --timezone UTC flag
and expect the correctly converted time (22:04 UTC from 15:04 -0700).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(gmail): add -z short flag for --timezone
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(gmail): add unit tests for resolveOutputLocation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs(gmail): clarify timezone flag help text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(gmail): add timezone conversion tests for formatGmailDateInLocation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(config): add default_timezone setting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(gmail): support GOG_TIMEZONE env var and config for timezone
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(config): add gog config command for timezone and settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(calendar): respect GOG_TIMEZONE and config for timezone
Update calendar time command to follow the same timezone priority as gmail:
1. --timezone flag (explicit)
2. GOG_TIMEZONE env var
3. Config file default_timezone
4. Fall back to Google Calendar's timezone (calendar-specific fallback)
Add getConfiguredTimezone helper that returns nil when no explicit timezone
is configured, allowing calendar commands to use their own fallback behavior.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(gmail): add tests for GOG_TIMEZONE env var and getConfiguredTimezone
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(config): warn on invalid timezone instead of error
When default_timezone in config is invalid, print a warning to stderr
and fall back to local timezone instead of returning a hard error.
Invalid flag/env var still returns errors (user mistake in current
session), but invalid config should not break the CLI (stale config).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(gmail): remove unused formatGmailDate, add nolint directive
- Remove unused formatGmailDate wrapper function (all callers use
formatGmailDateInLocation directly with explicit location)
- Add nolint:nilnil directive to getConfiguredTimezone with explanation
that nil return signals caller to use its own fallback
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(timezone): honor --timezone local
* refactor(cli): unify config/timezone helpers
* test(cmd): isolate config env in timezone tests
* refactor(config): centralize config key metadata
* fix(config): drop unused key spec lookup
* fix(config): standardize config key errors
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
- Add comprehensive unit tests for classroom helper functions
(date/time parsing, error wrapping, profile helpers)
- Add profileEmail() helper for nil-safe email extraction
- Fix nil pointer guards for Profile access (12 locations in
courses, rosters, and guardians)
- Add --topic filter for coursework and materials list commands
- Update docs/spec.md with new filter options
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>