zele 0.3.15 → 0.3.17

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 (80) hide show
  1. package/README.md +113 -33
  2. package/dist/api-utils.d.ts +7 -0
  3. package/dist/api-utils.js +12 -0
  4. package/dist/api-utils.js.map +1 -1
  5. package/dist/auth.d.ts +71 -9
  6. package/dist/auth.js +187 -11
  7. package/dist/auth.js.map +1 -1
  8. package/dist/calendar-time.js +6 -0
  9. package/dist/calendar-time.js.map +1 -1
  10. package/dist/cli.js +6 -1
  11. package/dist/cli.js.map +1 -1
  12. package/dist/commands/attachment.js +2 -0
  13. package/dist/commands/attachment.js.map +1 -1
  14. package/dist/commands/auth-cmd.js +104 -6
  15. package/dist/commands/auth-cmd.js.map +1 -1
  16. package/dist/commands/calendar.js +1 -1
  17. package/dist/commands/calendar.js.map +1 -1
  18. package/dist/commands/draft.js +9 -3
  19. package/dist/commands/draft.js.map +1 -1
  20. package/dist/commands/filter.d.ts +2 -0
  21. package/dist/commands/filter.js +64 -0
  22. package/dist/commands/filter.js.map +1 -0
  23. package/dist/commands/label.js +19 -9
  24. package/dist/commands/label.js.map +1 -1
  25. package/dist/commands/mail-actions.js +12 -2
  26. package/dist/commands/mail-actions.js.map +1 -1
  27. package/dist/commands/mail.js +194 -84
  28. package/dist/commands/mail.js.map +1 -1
  29. package/dist/commands/profile.js +25 -18
  30. package/dist/commands/profile.js.map +1 -1
  31. package/dist/db.js +24 -0
  32. package/dist/db.js.map +1 -1
  33. package/dist/generated/internal/class.js +2 -2
  34. package/dist/generated/internal/class.js.map +1 -1
  35. package/dist/generated/internal/prismaNamespace.d.ts +2 -0
  36. package/dist/generated/internal/prismaNamespace.js +2 -0
  37. package/dist/generated/internal/prismaNamespace.js.map +1 -1
  38. package/dist/generated/internal/prismaNamespaceBrowser.d.ts +2 -0
  39. package/dist/generated/internal/prismaNamespaceBrowser.js +2 -0
  40. package/dist/generated/internal/prismaNamespaceBrowser.js.map +1 -1
  41. package/dist/generated/models/Account.d.ts +97 -1
  42. package/dist/gmail-client.d.ts +42 -0
  43. package/dist/gmail-client.js +175 -9
  44. package/dist/gmail-client.js.map +1 -1
  45. package/dist/imap-smtp-client.d.ts +235 -0
  46. package/dist/imap-smtp-client.js +1225 -0
  47. package/dist/imap-smtp-client.js.map +1 -0
  48. package/dist/mail-tui.js +3 -2
  49. package/dist/mail-tui.js.map +1 -1
  50. package/dist/output.d.ts +2 -0
  51. package/dist/output.js +4 -0
  52. package/dist/output.js.map +1 -1
  53. package/package.json +9 -5
  54. package/schema.prisma +7 -5
  55. package/skills/zele/SKILL.md +141 -0
  56. package/src/api-utils.ts +13 -0
  57. package/src/auth.ts +283 -15
  58. package/src/calendar-time.test.ts +35 -0
  59. package/src/calendar-time.ts +5 -0
  60. package/src/cli.ts +6 -1
  61. package/src/commands/attachment.ts +1 -0
  62. package/src/commands/auth-cmd.ts +112 -6
  63. package/src/commands/calendar.ts +1 -1
  64. package/src/commands/draft.ts +7 -3
  65. package/src/commands/filter.ts +74 -0
  66. package/src/commands/label.ts +22 -11
  67. package/src/commands/mail-actions.ts +16 -3
  68. package/src/commands/mail.ts +207 -89
  69. package/src/commands/profile.ts +27 -17
  70. package/src/db.ts +28 -0
  71. package/src/generated/internal/class.ts +2 -2
  72. package/src/generated/internal/prismaNamespace.ts +2 -0
  73. package/src/generated/internal/prismaNamespaceBrowser.ts +2 -0
  74. package/src/generated/models/Account.ts +97 -1
  75. package/src/gmail-client.test.ts +155 -2
  76. package/src/gmail-client.ts +221 -16
  77. package/src/imap-smtp-client.ts +1381 -0
  78. package/src/mail-tui.tsx +3 -3
  79. package/src/output.ts +8 -1
  80. package/src/schema.sql +2 -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,53 @@ 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
+ ### IMAP/SMTP accounts
36
+
37
+ For non-Google providers (Fastmail, Outlook, Gmail with app passwords, any IMAP server):
38
+
39
+ ```bash
40
+ # Fastmail
41
+ zele login imap \
42
+ --email you@fastmail.com \
43
+ --imap-host imap.fastmail.com --imap-port 993 \
44
+ --smtp-host smtp.fastmail.com --smtp-port 465 \
45
+ --password "your-app-password"
46
+
47
+ # Gmail (app password)
48
+ zele login imap \
49
+ --email you@gmail.com \
50
+ --imap-host imap.gmail.com --imap-port 993 \
51
+ --smtp-host smtp.gmail.com --smtp-port 465 \
52
+ --password "your-app-password"
53
+
54
+ # Outlook
55
+ zele login imap \
56
+ --email you@outlook.com \
57
+ --imap-host outlook.office365.com --imap-port 993 \
58
+ --smtp-host smtp-mail.outlook.com --smtp-port 587 \
59
+ --password "your-password"
60
+
61
+ # IMAP-only (no sending)
62
+ zele login imap \
63
+ --email reader@example.com \
64
+ --imap-host imap.example.com --imap-port 993 \
65
+ --password "pass"
66
+ ```
67
+
68
+ Use `--imap-user` / `--smtp-user` if the login username differs from your email. Omit `--smtp-host` for read-only access.
69
+
70
+ ### Account management
71
+
33
72
  ```bash
34
- zele whoami # show authenticated accounts
73
+ zele whoami # show authenticated accounts (type, capabilities)
35
74
  zele logout # remove credentials
36
75
  ```
37
76
 
@@ -41,6 +80,7 @@ zele logout # remove credentials
41
80
 
42
81
  ```bash
43
82
  zele mail list # list recent threads
83
+ zele mail list --filter "is:unread" # only unread threads
44
84
  zele mail search "from:github" # search with Gmail query syntax
45
85
  zele mail read <thread-id> # read a thread
46
86
  zele mail send # send an email
@@ -59,46 +99,44 @@ zele mail trash <thread-id>
59
99
  zele mail untrash <thread-id>
60
100
  zele mail read-mark <thread-id>
61
101
  zele mail unread-mark <thread-id>
102
+ zele mail spam <thread-id>
103
+ zele mail unspam <thread-id>
62
104
  zele mail label <thread-id>
63
105
  zele mail trash-spam
64
106
  ```
65
107
 
66
108
  ### Search query syntax
67
109
 
68
- `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.
69
-
70
- | Operator | Example | Description |
71
- |---|---|---|
72
- | `from:` | `from:github` | Messages from a sender |
73
- | `to:` | `to:me@example.com` | Messages sent to a recipient |
74
- | `cc:` | `cc:team@example.com` | Messages where recipient was CC'd |
75
- | `subject:` | `subject:invoice` | Messages with words in the subject |
76
- | `is:unread` | `is:unread` | Unread messages |
77
- | `is:read` | `is:read` | Read messages |
78
- | `is:starred` | `is:starred` | Starred messages |
79
- | `has:attachment` | `has:attachment` | Messages with attachments (heuristic in watch) |
80
- | `-` (negate) | `-from:noreply` | Exclude matching messages |
81
- | `" "` (quotes) | `"exact phrase"` | Match an exact phrase |
82
- | `label:` | `label:work` | Messages with a specific label (search only) |
83
- | `in:` | `in:sent` | Messages in a folder (search only) |
84
- | `after:` | `after:2024/01/01` | Messages after a date (search only) |
85
- | `before:` | `before:2024/12/31` | Messages before a date (search only) |
86
- | `newer_than:` | `newer_than:7d` | Messages newer than a period (search only) |
87
- | `older_than:` | `older_than:1m` | Messages older than a period (search only) |
88
- | `filename:` | `filename:pdf` | Attachment filename (search only) |
89
- | `size:` / `larger:` / `smaller:` | `larger:5M` | Filter by message size (search only) |
90
- | `OR` | `from:a OR from:b` | Match either term (search only) |
91
- | `{ }` | `{from:a from:b}` | Group OR terms (search only) |
92
-
93
- Combine multiple operators to narrow results:
110
+ 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).
111
+
112
+ | Operator | Example | Google | IMAP |
113
+ |---|---|---|---|
114
+ | `from:` | `from:github` | yes | yes |
115
+ | `to:` | `to:me@example.com` | yes | yes |
116
+ | `subject:` | `subject:invoice` | yes | yes |
117
+ | `is:unread` | `is:unread` | yes | yes |
118
+ | `is:starred` | `is:starred` | yes | yes |
119
+ | `has:attachment` | `has:attachment` | yes | yes |
120
+ | `newer_than:` | `newer_than:7d` | yes | yes |
121
+ | `older_than:` | `older_than:1m` | yes | yes |
122
+ | `after:` | `after:2024/01/01` | yes | yes |
123
+ | `before:` | `before:2024/12/31` | yes | yes |
124
+ | `cc:` | `cc:team@example.com` | yes | no |
125
+ | `-` (negate) | `-from:noreply` | yes | no |
126
+ | `" "` (quotes) | `"exact phrase"` | yes | no |
127
+ | `label:` | `label:work` | yes | no |
128
+ | `in:` | `in:sent` | yes | no |
129
+ | `filename:` | `filename:pdf` | yes | no |
130
+ | `size:` / `larger:` / `smaller:` | `larger:5M` | yes | no |
131
+ | `OR` / `{ }` | `from:a OR from:b` | yes | no |
94
132
 
95
133
  ```bash
134
+ zele mail list --filter "is:unread"
135
+ zele mail list --filter "from:github newer_than:7d" --folder sent
96
136
  zele mail search "from:github is:unread newer_than:7d"
97
137
  zele mail watch --query "from:github has:attachment"
98
138
  ```
99
139
 
100
- 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.
101
-
102
140
  ### Drafts
103
141
 
104
142
  ```bash
@@ -108,7 +146,7 @@ zele draft send <draft-id>
108
146
  zele draft delete <draft-id>
109
147
  ```
110
148
 
111
- ### Labels
149
+ ### Labels (Google only)
112
150
 
113
151
  ```bash
114
152
  zele label list
@@ -117,7 +155,13 @@ zele label create <name>
117
155
  zele label delete <label-id>
118
156
  ```
119
157
 
120
- ### Calendar
158
+ ### Filters (Google only)
159
+
160
+ ```bash
161
+ zele mail filter list
162
+ ```
163
+
164
+ ### Calendar (Google only)
121
165
 
122
166
  ```bash
123
167
  zele cal list # list calendars
@@ -130,6 +174,24 @@ zele cal respond <event-id> # accept/decline
130
174
  zele cal freebusy # check availability
131
175
  ```
132
176
 
177
+ #### Shared / subscribed calendars
178
+
179
+ Zele uses Google CalDAV for calendar access. By default, Google only syncs calendars you **own** over CalDAV — shared or subscribed calendars (e.g. a partner's calendar) won't appear in `zele cal list` even after accepting the share invitation.
180
+
181
+ To fix this, visit Google's CalDAV sync settings and enable the shared calendar:
182
+
183
+ 1. Open **https://www.google.com/calendar/syncselect** (logged in as the account you use with zele)
184
+ 2. Check the box next to any shared calendar you want to access
185
+ 3. Click **Save**
186
+
187
+ After that, `zele cal list` will show the shared calendar and you can query it:
188
+
189
+ ```bash
190
+ zele cal events --calendar "other-person@gmail.com" --week
191
+ ```
192
+
193
+ > **Why is this needed?** Google's CalDAV endpoint only exposes calendars marked for sync (originally designed for mobile device sync). The Google Calendar web UI uses a different internal API, so calendars visible there may not appear via CalDAV until explicitly enabled at the sync settings page.
194
+
133
195
  ### Attachments
134
196
 
135
197
  ```bash
@@ -147,6 +209,24 @@ zele profile # show account info
147
209
 
148
210
  All commands support `--account <email>` to filter by account. Without it, commands fetch from all accounts and merge results.
149
211
 
212
+ 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.
213
+
214
+ ### Feature compatibility
215
+
216
+ | Feature | Google | IMAP/SMTP |
217
+ |---|---|---|
218
+ | List, read, search emails | yes | yes |
219
+ | Send, reply, forward | yes | yes (requires SMTP) |
220
+ | Star, archive, trash, mark read | yes | yes |
221
+ | Drafts | yes | yes |
222
+ | Attachments | yes | yes |
223
+ | Watch for new emails | yes | yes |
224
+ | Date/sender/subject filters | yes | yes |
225
+ | Labels | yes | no (IMAP uses folders) |
226
+ | Filters | yes | no |
227
+ | Calendar | yes | no |
228
+ | Gmail search operators | full | subset (see table above) |
229
+
150
230
  ## Output
151
231
 
152
232
  All structured data is output as YAML. In TTY mode, keys are colored for readability. Pipe output to other tools for scripting.
@@ -46,10 +46,17 @@ 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
+ }
49
53
  /** Detect auth-like errors from underlying libraries (tsdav string errors, googleapis structured errors).
50
54
  * Used inside clients to decide whether to return an AuthError.
51
55
  * NOTE: String matching here is intentional — this is the boundary layer that converts
52
56
  * untyped external library exceptions into typed AuthError values (errore "wrapping libraries" pattern). */
53
57
  export declare function isAuthLikeError(err: unknown): boolean;
58
+ /** Check if an error is specifically about missing OAuth scopes (not expired tokens or revoked access).
59
+ * When true, the user needs to `zele login` again to grant the new scope. */
60
+ export declare function isScopeError(err: unknown): boolean;
54
61
  export declare function isRateLimitError(err: any): boolean;
55
62
  export {};
package/dist/api-utils.js CHANGED
@@ -101,6 +101,12 @@ 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
+ }
104
110
  /** Detect auth-like errors from underlying libraries (tsdav string errors, googleapis structured errors).
105
111
  * Used inside clients to decide whether to return an AuthError.
106
112
  * NOTE: String matching here is intentional — this is the boundary layer that converts
@@ -115,6 +121,12 @@ export function isAuthLikeError(err) {
115
121
  const msg = String(err);
116
122
  return msg.includes('Invalid credentials') || msg.includes('Unauthorized') || msg.includes('invalid_grant');
117
123
  }
124
+ /** Check if an error is specifically about missing OAuth scopes (not expired tokens or revoked access).
125
+ * When true, the user needs to `zele login` again to grant the new scope. */
126
+ export function isScopeError(err) {
127
+ const msg = String(err);
128
+ return msg.includes('insufficient authentication scopes') || msg.includes('Insufficient Permission');
129
+ }
118
130
  // ---------------------------------------------------------------------------
119
131
  // Rate limit detection
120
132
  // ---------------------------------------------------------------------------
@@ -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[]>;