zele 0.3.16 → 0.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +155 -36
  2. package/dist/api-utils.d.ts +14 -0
  3. package/dist/api-utils.js +20 -0
  4. package/dist/api-utils.js.map +1 -1
  5. package/dist/auth.d.ts +71 -9
  6. package/dist/auth.js +186 -10
  7. package/dist/auth.js.map +1 -1
  8. package/dist/cli-types.d.ts +4 -0
  9. package/dist/cli-types.js +6 -0
  10. package/dist/cli-types.js.map +1 -0
  11. package/dist/cli.js +1 -5
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/attachment.d.ts +2 -2
  14. package/dist/commands/attachment.js +2 -0
  15. package/dist/commands/attachment.js.map +1 -1
  16. package/dist/commands/auth-cmd.d.ts +2 -2
  17. package/dist/commands/auth-cmd.js +104 -6
  18. package/dist/commands/auth-cmd.js.map +1 -1
  19. package/dist/commands/calendar.d.ts +2 -2
  20. package/dist/commands/calendar.js.map +1 -1
  21. package/dist/commands/draft.d.ts +2 -2
  22. package/dist/commands/draft.js +58 -4
  23. package/dist/commands/draft.js.map +1 -1
  24. package/dist/commands/filter.d.ts +2 -2
  25. package/dist/commands/filter.js +7 -2
  26. package/dist/commands/filter.js.map +1 -1
  27. package/dist/commands/label.d.ts +2 -2
  28. package/dist/commands/label.js +19 -9
  29. package/dist/commands/label.js.map +1 -1
  30. package/dist/commands/mail-actions.d.ts +2 -2
  31. package/dist/commands/mail-actions.js +290 -1
  32. package/dist/commands/mail-actions.js.map +1 -1
  33. package/dist/commands/mail.d.ts +2 -2
  34. package/dist/commands/mail.js +90 -23
  35. package/dist/commands/mail.js.map +1 -1
  36. package/dist/commands/profile.d.ts +2 -2
  37. package/dist/commands/profile.js +25 -18
  38. package/dist/commands/profile.js.map +1 -1
  39. package/dist/commands/watch.d.ts +2 -2
  40. package/dist/commands/watch.js.map +1 -1
  41. package/dist/db.js +24 -0
  42. package/dist/db.js.map +1 -1
  43. package/dist/generated/internal/class.js +2 -2
  44. package/dist/generated/internal/class.js.map +1 -1
  45. package/dist/generated/internal/prismaNamespace.d.ts +2 -0
  46. package/dist/generated/internal/prismaNamespace.js +2 -0
  47. package/dist/generated/internal/prismaNamespace.js.map +1 -1
  48. package/dist/generated/internal/prismaNamespaceBrowser.d.ts +2 -0
  49. package/dist/generated/internal/prismaNamespaceBrowser.js +2 -0
  50. package/dist/generated/internal/prismaNamespaceBrowser.js.map +1 -1
  51. package/dist/generated/models/Account.d.ts +97 -1
  52. package/dist/gmail-client.d.ts +73 -3
  53. package/dist/gmail-client.js +165 -5
  54. package/dist/gmail-client.js.map +1 -1
  55. package/dist/imap-smtp-client.d.ts +306 -0
  56. package/dist/imap-smtp-client.js +1349 -0
  57. package/dist/imap-smtp-client.js.map +1 -0
  58. package/dist/mail-tui.js.map +1 -1
  59. package/dist/unsubscribe.d.ts +76 -0
  60. package/dist/unsubscribe.js +224 -0
  61. package/dist/unsubscribe.js.map +1 -0
  62. package/package.json +6 -3
  63. package/schema.prisma +7 -5
  64. package/skills/zele/SKILL.md +26 -96
  65. package/src/api-utils.ts +20 -0
  66. package/src/auth.ts +282 -14
  67. package/src/cli-types.ts +8 -0
  68. package/src/cli.ts +2 -7
  69. package/src/commands/attachment.ts +3 -2
  70. package/src/commands/auth-cmd.ts +114 -8
  71. package/src/commands/calendar.ts +2 -2
  72. package/src/commands/draft.ts +65 -6
  73. package/src/commands/filter.ts +11 -5
  74. package/src/commands/label.ts +24 -13
  75. package/src/commands/mail-actions.ts +317 -5
  76. package/src/commands/mail.ts +97 -25
  77. package/src/commands/profile.ts +29 -19
  78. package/src/commands/watch.ts +2 -2
  79. package/src/db.ts +28 -0
  80. package/src/generated/internal/class.ts +2 -2
  81. package/src/generated/internal/prismaNamespace.ts +2 -0
  82. package/src/generated/internal/prismaNamespaceBrowser.ts +2 -0
  83. package/src/generated/models/Account.ts +97 -1
  84. package/src/gmail-client.test.ts +155 -2
  85. package/src/gmail-client.ts +258 -6
  86. package/src/imap-smtp-client.ts +1560 -0
  87. package/src/mail-tui.tsx +2 -1
  88. package/src/schema.sql +2 -0
  89. package/src/unsubscribe.test.ts +487 -0
  90. package/src/unsubscribe.ts +255 -0
package/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
  <br/>
3
3
  <br/>
4
4
  <h3>zele</h3>
5
- <p>Manage emails & calendar from your terminal. For you and your agents</p>
5
+ <p>Email & Calendar CLI Gmail, IMAP/SMTP, Google Calendar. For you and your agents</p>
6
6
  <br/>
7
7
  <br/>
8
8
  </div>
9
9
 
10
10
  ## Install
11
11
 
12
- Multi-account Gmail and Google Calendar client with OAuth2 auth, SQLite cache, and YAML output.
12
+ Multi-account email and calendar client supporting **Google OAuth** and **IMAP/SMTP** (Fastmail, Outlook, any provider). SQLite cache, YAML output.
13
13
 
14
14
  Requires [bun](https://bun.sh):
15
15
 
@@ -24,14 +24,74 @@ bun install -g zele
24
24
 
25
25
  ## Setup
26
26
 
27
+ ### Google accounts
28
+
27
29
  ```bash
28
30
  zele login
29
31
  ```
30
32
 
31
33
  Opens a browser for Google OAuth2. Repeat to add more accounts.
32
34
 
35
+ #### Remote / headless login (for agents)
36
+
37
+ `zele login` is interactive — it prints an authorization URL and waits for the redirect URL to be pasted back. In agent or headless environments, run it inside a `tmux` session so the process persists and can be driven programmatically:
38
+
33
39
  ```bash
34
- zele whoami # show authenticated accounts
40
+ # start login in a tmux session
41
+ tmux new-session -d -s zele-login 'zele login'
42
+
43
+ # read the authorization URL from tmux output
44
+ tmux capture-pane -t zele-login -p
45
+
46
+ # after the user completes consent in their browser, paste the redirect URL
47
+ tmux send-keys -t zele-login 'http://localhost:...?code=...' Enter
48
+
49
+ # verify login succeeded
50
+ tmux capture-pane -t zele-login -p
51
+ tmux kill-session -t zele-login
52
+ ```
53
+
54
+ IMAP/SMTP login is non-interactive and requires no tmux wrapper.
55
+
56
+ ### IMAP/SMTP accounts
57
+
58
+ For non-Google providers (Fastmail, Outlook, Gmail with app passwords, any IMAP server):
59
+
60
+ ```bash
61
+ # Fastmail
62
+ zele login imap \
63
+ --email you@fastmail.com \
64
+ --imap-host imap.fastmail.com --imap-port 993 \
65
+ --smtp-host smtp.fastmail.com --smtp-port 465 \
66
+ --password "your-app-password"
67
+
68
+ # Gmail (app password)
69
+ zele login imap \
70
+ --email you@gmail.com \
71
+ --imap-host imap.gmail.com --imap-port 993 \
72
+ --smtp-host smtp.gmail.com --smtp-port 465 \
73
+ --password "your-app-password"
74
+
75
+ # Outlook
76
+ zele login imap \
77
+ --email you@outlook.com \
78
+ --imap-host outlook.office365.com --imap-port 993 \
79
+ --smtp-host smtp-mail.outlook.com --smtp-port 587 \
80
+ --password "your-password"
81
+
82
+ # IMAP-only (no sending)
83
+ zele login imap \
84
+ --email reader@example.com \
85
+ --imap-host imap.example.com --imap-port 993 \
86
+ --password "pass"
87
+ ```
88
+
89
+ Use `--imap-user` / `--smtp-user` if the login username differs from your email. Omit `--smtp-host` for read-only access.
90
+
91
+ ### Account management
92
+
93
+ ```bash
94
+ zele whoami # show authenticated accounts (type, capabilities)
35
95
  zele logout # remove credentials
36
96
  ```
37
97
 
@@ -66,46 +126,59 @@ zele mail label <thread-id>
66
126
  zele mail trash-spam
67
127
  ```
68
128
 
69
- ### Search query syntax
129
+ All action commands accept **one or more thread IDs** and an optional `--account` flag. On Google accounts, archiving removes the `INBOX` label. On IMAP accounts, it moves the message to the server's Archive folder (`Archive`, `Archives`, `All Mail`, `[Gmail]/All Mail`, or `INBOX.Archive`).
130
+
131
+ ```bash
132
+ # archive a single thread
133
+ zele mail archive 18f3b7c9d2a1e4f0
70
134
 
71
- `mail search` and `mail watch --query` use [Gmail search operators](https://support.google.com/mail/answer/7190). `mail search` sends the query server-side (full Gmail support), while `mail watch --query` evaluates a subset client-side.
135
+ # archive multiple threads at once
136
+ zele mail archive 18f3b7c9d2a1e4f0 18f3b7c9d2a1e4f1 18f3b7c9d2a1e4f2
72
137
 
73
- | Operator | Example | Description |
74
- |---|---|---|
75
- | `from:` | `from:github` | Messages from a sender |
76
- | `to:` | `to:me@example.com` | Messages sent to a recipient |
77
- | `cc:` | `cc:team@example.com` | Messages where recipient was CC'd |
78
- | `subject:` | `subject:invoice` | Messages with words in the subject |
79
- | `is:unread` | `is:unread` | Unread messages |
80
- | `is:read` | `is:read` | Read messages |
81
- | `is:starred` | `is:starred` | Starred messages |
82
- | `has:attachment` | `has:attachment` | Messages with attachments (heuristic in watch) |
83
- | `-` (negate) | `-from:noreply` | Exclude matching messages |
84
- | `" "` (quotes) | `"exact phrase"` | Match an exact phrase |
85
- | `label:` | `label:work` | Messages with a specific label (search only) |
86
- | `in:` | `in:sent` | Messages in a folder (search only) |
87
- | `after:` | `after:2024/01/01` | Messages after a date (search only) |
88
- | `before:` | `before:2024/12/31` | Messages before a date (search only) |
89
- | `newer_than:` | `newer_than:7d` | Messages newer than a period (search only) |
90
- | `older_than:` | `older_than:1m` | Messages older than a period (search only) |
91
- | `filename:` | `filename:pdf` | Attachment filename (search only) |
92
- | `size:` / `larger:` / `smaller:` | `larger:5M` | Filter by message size (search only) |
93
- | `OR` | `from:a OR from:b` | Match either term (search only) |
94
- | `{ }` | `{from:a from:b}` | Group OR terms (search only) |
95
-
96
- Combine multiple operators to narrow results:
138
+ # archive from a specific account when you have multiple
139
+ zele mail archive 18f3b7c9d2a1e4f0 --account you@example.com
140
+
141
+ # bulk archive: pipe thread IDs from a search
142
+ zele mail search "from:noreply@github.com older_than:7d" \
143
+ | yq '.[].id' \
144
+ | xargs zele mail archive
145
+
146
+ # list archived threads later
147
+ zele mail list --filter "in:archive"
148
+ ```
149
+
150
+ ### Search query syntax
151
+
152
+ For **Google accounts**, `mail search` and `mail list --filter` use [Gmail search operators](https://support.google.com/mail/answer/7190) server-side. For **IMAP accounts**, queries are translated to IMAP SEARCH criteria (a subset is supported).
153
+
154
+ | Operator | Example | Google | IMAP |
155
+ |---|---|---|---|
156
+ | `from:` | `from:github` | yes | yes |
157
+ | `to:` | `to:me@example.com` | yes | yes |
158
+ | `subject:` | `subject:invoice` | yes | yes |
159
+ | `is:unread` | `is:unread` | yes | yes |
160
+ | `is:starred` | `is:starred` | yes | yes |
161
+ | `has:attachment` | `has:attachment` | yes | yes |
162
+ | `newer_than:` | `newer_than:7d` | yes | yes |
163
+ | `older_than:` | `older_than:1m` | yes | yes |
164
+ | `after:` | `after:2024/01/01` | yes | yes |
165
+ | `before:` | `before:2024/12/31` | yes | yes |
166
+ | `cc:` | `cc:team@example.com` | yes | no |
167
+ | `-` (negate) | `-from:noreply` | yes | no |
168
+ | `" "` (quotes) | `"exact phrase"` | yes | no |
169
+ | `label:` | `label:work` | yes | no |
170
+ | `in:` | `in:sent` | yes | no |
171
+ | `filename:` | `filename:pdf` | yes | no |
172
+ | `size:` / `larger:` / `smaller:` | `larger:5M` | yes | no |
173
+ | `OR` / `{ }` | `from:a OR from:b` | yes | no |
97
174
 
98
175
  ```bash
99
176
  zele mail list --filter "is:unread"
100
- zele mail list --filter "from:github has:attachment" --folder sent
177
+ zele mail list --filter "from:github newer_than:7d" --folder sent
101
178
  zele mail search "from:github is:unread newer_than:7d"
102
179
  zele mail watch --query "from:github has:attachment"
103
180
  ```
104
181
 
105
- `mail list --filter` accepts the same Gmail search operators as `mail search`, and combines with `--folder` and `--label`.
106
-
107
- Operators marked **(search only)** are handled server-side by Gmail and only available in `mail search`. Using them in `mail watch --query` prints a warning and skips the operator.
108
-
109
182
  ### Drafts
110
183
 
111
184
  ```bash
@@ -115,7 +188,7 @@ zele draft send <draft-id>
115
188
  zele draft delete <draft-id>
116
189
  ```
117
190
 
118
- ### Labels
191
+ ### Labels (Google only)
119
192
 
120
193
  ```bash
121
194
  zele label list
@@ -124,7 +197,13 @@ zele label create <name>
124
197
  zele label delete <label-id>
125
198
  ```
126
199
 
127
- ### Calendar
200
+ ### Filters (Google only)
201
+
202
+ ```bash
203
+ zele mail filter list
204
+ ```
205
+
206
+ ### Calendar (Google only)
128
207
 
129
208
  ```bash
130
209
  zele cal list # list calendars
@@ -172,10 +251,50 @@ zele profile # show account info
172
251
 
173
252
  All commands support `--account <email>` to filter by account. Without it, commands fetch from all accounts and merge results.
174
253
 
254
+ Google and IMAP/SMTP accounts work side by side — `mail list` merges results from both. Google-only features (labels, filters, calendar) show a helpful error when used with IMAP accounts.
255
+
256
+ ### Feature compatibility
257
+
258
+ | Feature | Google | IMAP/SMTP |
259
+ |---|---|---|
260
+ | List, read, search emails | yes | yes |
261
+ | Send, reply, forward | yes | yes (requires SMTP) |
262
+ | Star, archive, trash, mark read | yes | yes |
263
+ | Drafts | yes | yes |
264
+ | Attachments | yes | yes |
265
+ | Watch for new emails | yes | yes |
266
+ | Date/sender/subject filters | yes | yes |
267
+ | Labels | yes | no (IMAP uses folders) |
268
+ | Filters | yes | no |
269
+ | Calendar | yes | no |
270
+ | Gmail search operators | full | subset (see table above) |
271
+
175
272
  ## Output
176
273
 
177
274
  All structured data is output as YAML. In TTY mode, keys are colored for readability. Pipe output to other tools for scripting.
178
275
 
276
+ ## For AI agents
277
+
278
+ **Always run `zele --help` first.** The top-level help already contains every subcommand, option, and flag — there is no need to run `zele <command> --help` separately. The help output is the source of truth. Read it in full — never pipe through `head`, `tail`, or `sed` to truncate.
279
+
280
+ **Never use the TUI.** Running `zele` with no subcommand launches a human-facing terminal UI for browsing email. Agents must use the CLI subcommands (`zele mail list`, `zele cal events`, etc.) which output structured YAML that can be parsed and piped.
281
+
282
+ **Always run `zele whoami` before account-scoped commands.** When the user asks to check email "for a specific account" (e.g. "my work email", "my personal Gmail"), run `zele whoami` first to list connected accounts and find the exact address to pass to `--account`. Never guess the email — pick it from the `whoami` output. The output also shows account type (`google` or `imap_smtp`) and capabilities so you know which features are available.
283
+
284
+ ```bash
285
+ # list connected accounts first
286
+ zele whoami
287
+
288
+ # then scope commands to the right account
289
+ zele mail list --account user@work.com
290
+ ```
291
+
292
+ **Prefer YAML parsing over regex.** Pipe command output through `yq` to extract IDs and fields reliably:
293
+
294
+ ```bash
295
+ zele mail list --filter "is:unread" | yq '.[].id' | xargs zele mail archive
296
+ ```
297
+
179
298
  ## License
180
299
 
181
300
  ISC
@@ -46,6 +46,20 @@ declare const ApiError_base: errore.FactoryTaggedErrorClass<"ApiError", "API cal
46
46
  /** Returned when a non-auth, non-ratelimit API call fails. */
47
47
  export declare class ApiError extends ApiError_base {
48
48
  }
49
+ declare const UnsupportedError_base: errore.FactoryTaggedErrorClass<"UnsupportedError", "$feature is not available for $accountType accounts. $hint", Error>;
50
+ /** Returned when a command requires a capability (e.g. gmail labels) that the account doesn't support. */
51
+ export declare class UnsupportedError extends UnsupportedError_base {
52
+ }
53
+ declare const UnsubscribeUnavailableError_base: errore.FactoryTaggedErrorClass<"UnsubscribeUnavailableError", "No List-Unsubscribe header on thread $threadId", Error>;
54
+ /** Returned when a thread has no List-Unsubscribe header (RFC 2369) so no
55
+ * standardized unsubscribe mechanism is available. */
56
+ export declare class UnsubscribeUnavailableError extends UnsubscribeUnavailableError_base {
57
+ }
58
+ declare const UnsubscribeFailedError_base: errore.FactoryTaggedErrorClass<"UnsubscribeFailedError", "Unsubscribe via $mechanism failed: $reason", Error>;
59
+ /** Returned when the unsubscribe attempt itself failed (HTTP error, SMTP
60
+ * send failure, redirect returned when RFC 8058 forbids it, etc.). */
61
+ export declare class UnsubscribeFailedError extends UnsubscribeFailedError_base {
62
+ }
49
63
  /** Detect auth-like errors from underlying libraries (tsdav string errors, googleapis structured errors).
50
64
  * Used inside clients to decide whether to return an AuthError.
51
65
  * NOTE: String matching here is intentional — this is the boundary layer that converts
package/dist/api-utils.js CHANGED
@@ -101,6 +101,26 @@ export class ApiError extends errore.createTaggedError({
101
101
  message: 'API call failed: $reason',
102
102
  }) {
103
103
  }
104
+ /** Returned when a command requires a capability (e.g. gmail labels) that the account doesn't support. */
105
+ export class UnsupportedError extends errore.createTaggedError({
106
+ name: 'UnsupportedError',
107
+ message: '$feature is not available for $accountType accounts. $hint',
108
+ }) {
109
+ }
110
+ /** Returned when a thread has no List-Unsubscribe header (RFC 2369) so no
111
+ * standardized unsubscribe mechanism is available. */
112
+ export class UnsubscribeUnavailableError extends errore.createTaggedError({
113
+ name: 'UnsubscribeUnavailableError',
114
+ message: 'No List-Unsubscribe header on thread $threadId',
115
+ }) {
116
+ }
117
+ /** Returned when the unsubscribe attempt itself failed (HTTP error, SMTP
118
+ * send failure, redirect returned when RFC 8058 forbids it, etc.). */
119
+ export class UnsubscribeFailedError extends errore.createTaggedError({
120
+ name: 'UnsubscribeFailedError',
121
+ message: 'Unsubscribe via $mechanism failed: $reason',
122
+ }) {
123
+ }
104
124
  /** Detect auth-like errors from underlying libraries (tsdav string errors, googleapis structured errors).
105
125
  * Used inside clients to decide whether to return an AuthError.
106
126
  * NOTE: String matching here is intentional — this is the boundary layer that converts
@@ -1 +1 @@
1
- {"version":3,"file":"api-utils.js","sourceRoot":"","sources":["../src/api-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-utils.js","sourceRoot":"","sources":["../src/api-utils.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts CHANGED
@@ -1,6 +1,32 @@
1
1
  import { OAuth2Client } from 'google-auth-library';
2
2
  import { GmailClient } from './gmail-client.js';
3
3
  import { CalendarClient } from './calendar-client.js';
4
+ import { ImapSmtpClient } from './imap-smtp-client.js';
5
+ export type AccountType = 'google' | 'imap_smtp';
6
+ export declare const IMAP_SMTP_APP_ID: "imap_smtp";
7
+ export interface ImapCredentials {
8
+ host: string;
9
+ port: number;
10
+ user: string;
11
+ password: string;
12
+ tls: boolean;
13
+ }
14
+ export interface SmtpCredentials {
15
+ host: string;
16
+ port: number;
17
+ user: string;
18
+ password: string;
19
+ tls: boolean;
20
+ }
21
+ /** Stored in the `tokens` column for imap_smtp accounts. */
22
+ export interface ImapSmtpCredentials {
23
+ imap?: ImapCredentials;
24
+ smtp?: SmtpCredentials;
25
+ }
26
+ /** Capabilities an account can have. */
27
+ export type AccountCapability = 'gmail' | 'calendar' | 'smtp' | 'imap';
28
+ export declare function parseCapabilities(raw: string): AccountCapability[];
29
+ export declare function hasCapability(capabilities: string | AccountCapability[], cap: AccountCapability): boolean;
4
30
  /**
5
31
  * Create an OAuth2Client. If appId is provided, looks up the matching
6
32
  * client credentials from OAUTH_CLIENTS by client ID. Falls back to
@@ -10,6 +36,8 @@ export declare function createOAuth2Client(appId?: string): OAuth2Client;
10
36
  export interface AccountId {
11
37
  email: string;
12
38
  appId: string;
39
+ accountType: AccountType;
40
+ capabilities: AccountCapability[];
13
41
  }
14
42
  interface BrowserAuthOptions {
15
43
  openBrowser?: boolean;
@@ -25,28 +53,60 @@ export declare function login(appId?: string, options?: BrowserAuthOptions): Pro
25
53
  appId: string;
26
54
  client: GmailClient;
27
55
  } | Error>;
56
+ export interface LoginImapOptions {
57
+ email: string;
58
+ imapHost: string;
59
+ imapPort?: number;
60
+ smtpHost?: string;
61
+ smtpPort?: number;
62
+ password?: string;
63
+ imapUser?: string;
64
+ imapPassword?: string;
65
+ smtpUser?: string;
66
+ smtpPassword?: string;
67
+ tls?: boolean;
68
+ }
69
+ /**
70
+ * Login with IMAP/SMTP credentials. Tests connections before saving.
71
+ * Returns an error value if validation or connection test fails.
72
+ */
73
+ export declare function loginImap(options: LoginImapOptions): Promise<{
74
+ email: string;
75
+ appId: string;
76
+ } | Error>;
28
77
  export declare function logout(email: string): Promise<void | Error>;
29
78
  export declare function listAccounts(): Promise<AccountId[]>;
79
+ /** Entry returned by getClients — client is GmailClient for Google accounts, ImapSmtpClient for IMAP/SMTP. */
80
+ export interface ClientEntry {
81
+ email: string;
82
+ appId: string;
83
+ accountType: AccountType;
84
+ capabilities: AccountCapability[];
85
+ client: GmailClient | ImapSmtpClient;
86
+ }
30
87
  /**
31
- * Get authenticated GmailClient instances for all accounts (or filtered by email list).
88
+ * Get authenticated client instances for all accounts (or filtered by email list).
89
+ * Returns GmailClient for Google accounts and ImapSmtpClient for IMAP/SMTP accounts.
32
90
  * If no accounts are registered, throws with a helpful message.
33
91
  */
34
- export declare function getClients(accounts?: string[]): Promise<Array<{
35
- email: string;
36
- appId: string;
37
- client: GmailClient;
38
- }>>;
92
+ export declare function getClients(accounts?: string[]): Promise<ClientEntry[]>;
39
93
  /**
40
- * Get a single authenticated GmailClient. Errors if multiple accounts exist
94
+ * Get a single authenticated client. Errors if multiple accounts exist
41
95
  * and no --account filter was provided.
42
96
  */
43
- export declare function getClient(accounts?: string[]): Promise<{
97
+ export declare function getClient(accounts?: string[]): Promise<ClientEntry>;
98
+ /**
99
+ * Get a single authenticated GmailClient. Errors if account is not a Google account.
100
+ * Use this for commands that require Gmail-specific features.
101
+ */
102
+ export declare function getGmailClient(accounts?: string[]): Promise<{
44
103
  email: string;
45
104
  appId: string;
46
105
  client: GmailClient;
47
106
  }>;
48
107
  /**
49
- * Get authenticated CalendarClient instances for all accounts (or filtered by email list).
108
+ * Get authenticated CalendarClient instances for Google accounts only.
109
+ * IMAP/SMTP accounts are silently skipped (calendar requires Google OAuth).
50
110
  */
51
111
  export declare function getCalendarClients(accounts?: string[]): Promise<Array<{
52
112
  email: string;
@@ -65,6 +125,8 @@ export declare function getCalendarClient(accounts?: string[]): Promise<{
65
125
  export interface AuthStatus {
66
126
  email: string;
67
127
  appId: string;
128
+ accountType: AccountType;
129
+ capabilities: AccountCapability[];
68
130
  expiresAt?: Date;
69
131
  }
70
132
  export declare function getAuthStatuses(): Promise<AuthStatus[]>;