@qwanyx/stack 0.2.101 → 0.2.103

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.
@@ -59,17 +59,19 @@ export declare class MailClient {
59
59
  /**
60
60
  * Move emails to trash (soft delete)
61
61
  * Tries multiple folder names for Gmail locales
62
+ * Note: This uses IMAP directly - for Gmail API accounts, use the trash endpoint instead
62
63
  * @param sourceFolder - The folder where the emails currently are (default: INBOX)
63
64
  */
64
- trashEmails(accountId: string, uids: number[], sourceFolder?: string): Promise<{
65
+ trashEmails(accountId: string, uids: (number | string)[], sourceFolder?: string): Promise<{
65
66
  success: boolean;
66
67
  moved: number;
67
68
  }>;
68
69
  /**
69
70
  * Archive emails (remove from inbox, keep in All Mail)
71
+ * Note: This uses IMAP directly - for Gmail API accounts, use the archive endpoint instead
70
72
  * @param sourceFolder - The folder where the emails currently are (default: INBOX)
71
73
  */
72
- archiveEmails(accountId: string, uids: number[], sourceFolder?: string): Promise<{
74
+ archiveEmails(accountId: string, uids: (number | string)[], sourceFolder?: string): Promise<{
73
75
  success: boolean;
74
76
  archived: number;
75
77
  }>;
@@ -88,9 +90,10 @@ export declare class MailClient {
88
90
  /**
89
91
  * Get a single email by UID with full body content (server-side parsing)
90
92
  * Returns attachments list from backend
93
+ * @param uid - IMAP uses numeric UID, Gmail API uses string message ID
91
94
  */
92
- getEmail(accountId: string, uid: number, folder?: string): Promise<{
93
- uid: number;
95
+ getEmail(accountId: string, uid: number | string, folder?: string): Promise<{
96
+ uid: number | string;
94
97
  from: string;
95
98
  subject: string;
96
99
  date: string;
@@ -100,13 +103,16 @@ export declare class MailClient {
100
103
  filename: string;
101
104
  content_type: string;
102
105
  size: number;
106
+ attachment_id?: string;
103
107
  }>;
104
108
  } | null>;
105
109
  /**
106
110
  * Get a specific attachment from an email
107
111
  * Returns base64-encoded content for download
112
+ * @param uid - IMAP uses numeric UID, Gmail API uses string message ID
113
+ * @param attachmentIdOrIndex - Gmail uses attachment_id string, IMAP uses numeric index
108
114
  */
109
- getAttachment(accountId: string, uid: number, attachmentIndex: number, folder?: string): Promise<{
115
+ getAttachment(accountId: string, uid: number | string, attachmentIdOrIndex: number | string, folder?: string): Promise<{
110
116
  filename: string;
111
117
  content_type: string;
112
118
  size: number;
@@ -134,9 +140,10 @@ export declare class MailClient {
134
140
  /**
135
141
  * Get email with client-side parsing using postal-mime
136
142
  * This handles CID embedded images by converting them to base64 data URIs
143
+ * Note: This method uses IMAP directly and may not work with Gmail API accounts
137
144
  */
138
- getEmailParsed(accountId: string, uid: number, folder?: string): Promise<{
139
- uid: number;
145
+ getEmailParsed(accountId: string, uid: number | string, folder?: string): Promise<{
146
+ uid: number | string;
140
147
  from: string;
141
148
  subject: string;
142
149
  date: string;
@@ -229,4 +236,58 @@ export declare class MailClient {
229
236
  message_id?: string;
230
237
  error?: string;
231
238
  }>;
239
+ /**
240
+ * Get Gmail OAuth authorization URL
241
+ * Opens this URL in a popup to start the OAuth flow
242
+ * @param accountId - Optional account ID (defaults to 'gmail')
243
+ * @param redirectUri - Optional custom redirect URI
244
+ */
245
+ getGmailAuthUrl(accountId?: string, redirectUri?: string): Promise<{
246
+ auth_url: string;
247
+ state: string;
248
+ }>;
249
+ /**
250
+ * Check if an account is connected via Gmail API
251
+ * @param accountId - Account to check
252
+ */
253
+ isGmailConnected(accountId: string): Promise<boolean>;
254
+ /**
255
+ * Disconnect Gmail account (removes OAuth tokens, switches back to IMAP)
256
+ * @param accountId - Account to disconnect
257
+ */
258
+ disconnectGmail(accountId: string): Promise<{
259
+ success: boolean;
260
+ error?: string;
261
+ }>;
262
+ /**
263
+ * Search for an email via Gmail API by subject and/or from
264
+ * Use this as a fallback when UID-based fetch fails for Gmail accounts
265
+ * @param accountId - Account to search
266
+ * @param subject - Subject to search for (partial match)
267
+ * @param from - From address to search for
268
+ */
269
+ gmailSearchMessage(accountId: string, subject?: string, from?: string): Promise<{
270
+ uid: string;
271
+ from: string;
272
+ subject: string;
273
+ date: string;
274
+ body: string;
275
+ seen: boolean;
276
+ attachments?: Array<{
277
+ filename: string;
278
+ content_type: string;
279
+ size: number;
280
+ attachment_id?: string;
281
+ }>;
282
+ } | null>;
283
+ /**
284
+ * Open Gmail OAuth popup and wait for result
285
+ * Returns a promise that resolves when OAuth completes or rejects on error
286
+ * @param accountId - Optional account ID
287
+ */
288
+ connectGmail(accountId?: string): Promise<{
289
+ success: boolean;
290
+ email?: string;
291
+ error?: string;
292
+ }>;
232
293
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import React from 'react';
6
6
  export interface EmailMessage {
7
- uid: number;
7
+ uid: number | string;
8
8
  subject: string;
9
9
  from: string;
10
10
  date: string;
@@ -24,13 +24,13 @@ export interface MailProps {
24
24
  emptyMessage?: string;
25
25
  autoLoad?: boolean;
26
26
  onSelect?: (email: EmailMessage) => void;
27
- onSelectionChange?: (uids: number[]) => void;
28
- onDelete?: (uids: number[]) => void;
27
+ onSelectionChange?: (uids: (number | string)[]) => void;
28
+ onDelete?: (uids: (number | string)[]) => void;
29
29
  onError?: (error: Error) => void;
30
30
  onLoad?: (emails: EmailMessage[]) => void;
31
31
  renderItem?: (email: EmailMessage, selected: boolean) => React.ReactNode;
32
32
  renderDetail?: (email: EmailMessage) => React.ReactNode;
33
- renderActions?: (selectedUids: number[], actions: MailActions) => React.ReactNode;
33
+ renderActions?: (selectedUids: (number | string)[], actions: MailActions) => React.ReactNode;
34
34
  renderEmpty?: () => React.ReactNode;
35
35
  renderLoading?: () => React.ReactNode;
36
36
  theme?: MailTheme;
@@ -40,6 +40,8 @@ export interface MailComposerProps {
40
40
  placeholder?: string;
41
41
  /** Additional CSS class */
42
42
  className?: string;
43
+ /** Hide the To field (when recipient is controlled externally) */
44
+ hideToField?: boolean;
43
45
  /** Minimum height for editor */
44
46
  minHeight?: string;
45
47
  /** Custom send button text */
@@ -52,6 +54,14 @@ export interface MailComposerProps {
52
54
  onAiProofread?: (text: string) => Promise<string>;
53
55
  /** AI callback: rewrite text */
54
56
  onAiRewrite?: (text: string) => Promise<string>;
57
+ /** AI callback: generate email from prompt */
58
+ onAiGenerate?: (prompt: string, context: {
59
+ to: string;
60
+ subject: string;
61
+ }, options: {
62
+ useNotes: boolean;
63
+ addSignature: boolean;
64
+ }) => Promise<string>;
55
65
  /** Content to render above the toolbar (e.g., AudioEditor) */
56
66
  renderAboveToolbar?: React.ReactNode;
57
67
  }
@@ -81,4 +91,4 @@ export interface MailComposerTheme extends MailEditorTheme {
81
91
  attachmentBackground?: string;
82
92
  attachmentBorder?: string;
83
93
  }
84
- export declare function MailComposer({ to: initialTo, subject: initialSubject, body: initialBody, replyTo, onSend, onCancel, onBodyChange, externalUpdate, insertText, insertTextTrigger, theme: themeProp, disabled, showCcBcc, placeholder, className, minHeight, sendButtonText, hideCancelButton, onAiRestructure, onAiProofread, onAiRewrite, renderAboveToolbar, }: MailComposerProps): import("react/jsx-runtime").JSX.Element;
94
+ export declare function MailComposer({ to: initialTo, subject: initialSubject, body: initialBody, replyTo, onSend, onCancel, onBodyChange, externalUpdate, insertText, insertTextTrigger, theme: themeProp, disabled, showCcBcc, placeholder, className, hideToField, minHeight, hideCancelButton, onAiRestructure, onAiProofread, onAiRewrite, onAiGenerate, renderAboveToolbar, }: MailComposerProps): import("react/jsx-runtime").JSX.Element;
@@ -11,4 +11,4 @@
11
11
  */
12
12
  import { GraphNode } from '../../types';
13
13
  import type { QMapProps } from './types';
14
- export declare function QMap<T extends GraphNode = GraphNode>({ viewNode, nodes, edges, renderNode, defaultNodeWidth, defaultNodeHeight, onNodeMove, onNodeClick, onNodeDoubleClick, onNodeContextMenu, selectedIds: controlledSelectedIds, onSelectionChange, onEdgeClick, onViewChange, onTransformChange, minZoom, maxZoom, initialTransform, defaultEdgeStyle, defaultEdgeColor, defaultEdgeWidth, draggable, selectable, zoomable, pannable, className, style, background, showGrid, gridSize }: QMapProps<T>): import("react/jsx-runtime").JSX.Element;
14
+ export declare function QMap<T extends GraphNode = GraphNode>({ viewNode, nodes, edges, renderNode, defaultNodeWidth, defaultNodeHeight, onNodeMove, onNodeDrag, onNodeClick, onNodeDoubleClick, onNodeContextMenu, selectedIds: controlledSelectedIds, onSelectionChange, onEdgeClick, onViewChange, onTransformChange, minZoom, maxZoom, initialTransform, defaultEdgeStyle, defaultEdgeColor, defaultEdgeWidth, draggable, selectable, zoomable, pannable, className, style, background, showGrid, gridSize }: QMapProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -47,6 +47,8 @@ export interface QMapProps<T extends GraphNode = GraphNode> {
47
47
  defaultNodeWidth?: number;
48
48
  defaultNodeHeight?: number;
49
49
  onNodeMove?: (nodeId: string, x: number, y: number) => void;
50
+ /** Called during node drag (real-time position updates) */
51
+ onNodeDrag?: (nodeId: string, x: number, y: number) => void;
50
52
  onNodeClick?: (node: T, event: React.MouseEvent) => void;
51
53
  onNodeDoubleClick?: (node: T, event: React.MouseEvent) => void;
52
54
  onNodeContextMenu?: (node: T, event: React.MouseEvent) => void;