@plotday/twister 0.47.0 → 0.49.0

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 (123) hide show
  1. package/bin/commands/generate.js +5 -5
  2. package/bin/commands/generate.js.map +1 -1
  3. package/bin/templates/AGENTS.template.md +8 -2
  4. package/bin/utils/bundle.js +14 -0
  5. package/bin/utils/bundle.js.map +1 -1
  6. package/cli/templates/AGENTS.template.md +8 -2
  7. package/dist/connector.d.ts +67 -7
  8. package/dist/connector.d.ts.map +1 -1
  9. package/dist/connector.js +15 -5
  10. package/dist/connector.js.map +1 -1
  11. package/dist/docs/assets/hierarchy.js +1 -1
  12. package/dist/docs/assets/navigation.js +1 -1
  13. package/dist/docs/assets/search.js +1 -1
  14. package/dist/docs/classes/index.Connector.html +58 -49
  15. package/dist/docs/classes/index.Imap.html +1 -1
  16. package/dist/docs/classes/index.Options.html +1 -1
  17. package/dist/docs/classes/index.Smtp.html +1 -1
  18. package/dist/docs/classes/tools_ai.AI.html +1 -1
  19. package/dist/docs/classes/tools_callbacks.Callbacks.html +1 -1
  20. package/dist/docs/classes/tools_integrations.Integrations.html +21 -5
  21. package/dist/docs/classes/tools_network.Network.html +1 -1
  22. package/dist/docs/classes/tools_plot.Plot.html +1 -1
  23. package/dist/docs/classes/tools_store.Store.html +1 -1
  24. package/dist/docs/classes/tools_tasks.Tasks.html +1 -1
  25. package/dist/docs/classes/tools_twists.Twists.html +1 -1
  26. package/dist/docs/classes/twist.Twist.html +28 -28
  27. package/dist/docs/documents/Building_Connectors.html +8 -1
  28. package/dist/docs/documents/CLI_Reference.html +6 -4
  29. package/dist/docs/enums/tag.Tag.html +11 -1
  30. package/dist/docs/enums/tools_integrations.AuthProvider.html +14 -12
  31. package/dist/docs/hierarchy.html +1 -1
  32. package/dist/docs/media/AGENTS.md +298 -775
  33. package/dist/docs/media/MULTI_USER_AUTH.md +6 -4
  34. package/dist/docs/media/SYNC_STRATEGIES.md +20 -14
  35. package/dist/docs/modules/index.html +1 -1
  36. package/dist/docs/types/index.CreateLinkDraft.html +7 -12
  37. package/dist/docs/types/index.NoteWriteBackResult.html +38 -0
  38. package/dist/docs/types/tools_integrations.ArchiveLinkFilter.html +5 -5
  39. package/dist/docs/types/tools_integrations.AuthToken.html +4 -4
  40. package/dist/docs/types/tools_integrations.Authorization.html +4 -4
  41. package/dist/llm-docs/connector.d.ts +1 -1
  42. package/dist/llm-docs/connector.d.ts.map +1 -1
  43. package/dist/llm-docs/connector.js +1 -1
  44. package/dist/llm-docs/connector.js.map +1 -1
  45. package/dist/llm-docs/tag.d.ts +1 -1
  46. package/dist/llm-docs/tag.d.ts.map +1 -1
  47. package/dist/llm-docs/tag.js +1 -1
  48. package/dist/llm-docs/tag.js.map +1 -1
  49. package/dist/llm-docs/tools/integrations.d.ts +1 -1
  50. package/dist/llm-docs/tools/integrations.d.ts.map +1 -1
  51. package/dist/llm-docs/tools/integrations.js +1 -1
  52. package/dist/llm-docs/tools/integrations.js.map +1 -1
  53. package/dist/llm-docs/twist-guide-template.d.ts +1 -1
  54. package/dist/llm-docs/twist-guide-template.d.ts.map +1 -1
  55. package/dist/llm-docs/twist-guide-template.js +1 -1
  56. package/dist/llm-docs/twist-guide-template.js.map +1 -1
  57. package/dist/llm-docs/twist.d.ts +1 -1
  58. package/dist/llm-docs/twist.d.ts.map +1 -1
  59. package/dist/llm-docs/twist.js +1 -1
  60. package/dist/llm-docs/twist.js.map +1 -1
  61. package/dist/tag.d.ts +11 -1
  62. package/dist/tag.d.ts.map +1 -1
  63. package/dist/tag.js +10 -0
  64. package/dist/tag.js.map +1 -1
  65. package/dist/tools/integrations.d.ts +25 -1
  66. package/dist/tools/integrations.d.ts.map +1 -1
  67. package/dist/tools/integrations.js +2 -0
  68. package/dist/tools/integrations.js.map +1 -1
  69. package/dist/twist-guide.d.ts +1 -1
  70. package/dist/twist-guide.d.ts.map +1 -1
  71. package/dist/twist.d.ts +2 -1
  72. package/dist/twist.d.ts.map +1 -1
  73. package/dist/twist.js.map +1 -1
  74. package/dist/utils/markdown.d.ts +27 -0
  75. package/dist/utils/markdown.d.ts.map +1 -0
  76. package/dist/utils/markdown.js +82 -0
  77. package/dist/utils/markdown.js.map +1 -0
  78. package/package.json +7 -1
  79. package/src/connector.ts +427 -0
  80. package/src/creator-docs.ts +29 -0
  81. package/src/index.ts +10 -0
  82. package/src/llm-docs/connector.ts +8 -0
  83. package/src/llm-docs/index.ts +48 -0
  84. package/src/llm-docs/options.ts +8 -0
  85. package/src/llm-docs/plot.ts +8 -0
  86. package/src/llm-docs/schedule.ts +8 -0
  87. package/src/llm-docs/tag.ts +8 -0
  88. package/src/llm-docs/tool.ts +8 -0
  89. package/src/llm-docs/tools/ai.ts +8 -0
  90. package/src/llm-docs/tools/callbacks.ts +8 -0
  91. package/src/llm-docs/tools/imap.ts +8 -0
  92. package/src/llm-docs/tools/integrations.ts +8 -0
  93. package/src/llm-docs/tools/network.ts +8 -0
  94. package/src/llm-docs/tools/plot.ts +8 -0
  95. package/src/llm-docs/tools/smtp.ts +8 -0
  96. package/src/llm-docs/tools/store.ts +8 -0
  97. package/src/llm-docs/tools/tasks.ts +8 -0
  98. package/src/llm-docs/tools/twists.ts +8 -0
  99. package/src/llm-docs/twist-guide-template.ts +8 -0
  100. package/src/llm-docs/twist.ts +8 -0
  101. package/src/options.ts +115 -0
  102. package/src/plot.ts +1068 -0
  103. package/src/schedule.ts +203 -0
  104. package/src/tag.ts +54 -0
  105. package/src/tool.ts +377 -0
  106. package/src/tools/ai.ts +845 -0
  107. package/src/tools/callbacks.ts +134 -0
  108. package/src/tools/imap.ts +266 -0
  109. package/src/tools/index.ts +10 -0
  110. package/src/tools/integrations.ts +352 -0
  111. package/src/tools/network.ts +240 -0
  112. package/src/tools/plot.ts +692 -0
  113. package/src/tools/smtp.ts +166 -0
  114. package/src/tools/store.ts +149 -0
  115. package/src/tools/tasks.ts +137 -0
  116. package/src/tools/twists.ts +228 -0
  117. package/src/twist-guide.ts +9 -0
  118. package/src/twist.ts +436 -0
  119. package/src/utils/hash.ts +8 -0
  120. package/src/utils/markdown.ts +94 -0
  121. package/src/utils/serializable.ts +54 -0
  122. package/src/utils/types.ts +130 -0
  123. package/src/utils/uuid.ts +9 -0
@@ -0,0 +1,134 @@
1
+ import { ITool } from "..";
2
+ import { Serializable } from "../utils/types";
3
+
4
+ /**
5
+ * Represents a callback token for persistent function references.
6
+ *
7
+ * Callbacks enable tools and twists to create persistent references to functions
8
+ * that can survive worker restarts and be invoked across different execution contexts.
9
+ *
10
+ * This is a branded strin
11
+ * type to prevent mixing callback tokens with regular strings.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const callback = await this.callback(this.onCalendarSelected, "primary", "google");
16
+ * ```
17
+ */
18
+ export type Callback = string & { readonly __brand: "Callback" };
19
+
20
+ /**
21
+ * Built-in tool for creating and managing persistent callback references.
22
+ *
23
+ * The Callbacks tool enables twists and tools to create callback links that persist
24
+ * across worker invocations and restarts. This is essential for webhook handlers,
25
+ * scheduled operations, and user interaction flows that need to survive runtime
26
+ * boundaries.
27
+ *
28
+ * **Note:** Callback methods are also available directly on Twist and Tool classes
29
+ * via `this.callback()`, `this.deleteCallback()`, `this.deleteAllCallbacks()`, and
30
+ * `this.run()`. This is the recommended approach for most use cases.
31
+ *
32
+ * **When to use callbacks:**
33
+ * - Webhook handlers that need persistent function references
34
+ * - Scheduled operations that run after worker timeouts
35
+ * - User interaction actions (ActionType.callback)
36
+ * - Cross-tool communication that survives restarts
37
+ *
38
+ * **Type Safety:**
39
+ * Callbacks are fully type-safe - extraArgs are type-checked against the function signature.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * class MyTool extends Tool {
44
+ * async setupWebhook() {
45
+ * // Using built-in callback method (recommended)
46
+ * const callback = await this.callback(this.handleWebhook, "calendar");
47
+ * return `https://api.plot.day/webhook/${callback}`;
48
+ * }
49
+ *
50
+ * async handleWebhook(data: any, webhookType: string) {
51
+ * console.log("Webhook received:", data, webhookType);
52
+ * }
53
+ * }
54
+ * ```
55
+ */
56
+ export abstract class Callbacks extends ITool {
57
+ /**
58
+ * Creates a persistent callback to a method on the current class.
59
+ *
60
+ * @param fn - The function to callback
61
+ * @param extraArgs - Additional arguments to pass to the function after any passed by the caller
62
+ * @returns Promise resolving to a persistent callback token
63
+ */
64
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
65
+ abstract create<
66
+ TArgs extends Serializable[],
67
+ F extends (...extraArgs: TArgs) => any
68
+ >(fn: F, ...extraArgs: TArgs): Promise<Callback>;
69
+ // Variation when called provides the first argument
70
+ abstract create<
71
+ TArgs extends Serializable[],
72
+ F extends (arg1: any, ...extraArgs: TArgs) => any
73
+ >(fn: F, ...extraArgs: TArgs): Promise<Callback>;
74
+
75
+ /**
76
+ * Creates a persistent callback to a function from the parent twist/tool.
77
+ * Use this when the callback function is passed in from outside this class.
78
+ *
79
+ * @param fn - The function to callback
80
+ * @param extraArgs - Additional arguments to pass to the function after any passed by the caller
81
+ * @returns Promise resolving to a callback token
82
+ */
83
+ abstract createFromParent<
84
+ TArgs extends Serializable[],
85
+ F extends (...extraArgs: TArgs) => any
86
+ >(fn: F, ...extraArgs: TArgs): Promise<Callback>;
87
+ // Variation when called provides the first argument
88
+ abstract createFromParent<
89
+ TArgs extends Serializable[],
90
+ F extends (arg1: any, ...extraArgs: TArgs) => any
91
+ >(fn: F, ...extraArgs: TArgs): Promise<Callback>;
92
+
93
+ // <
94
+ // DeferredArgs extends any[],
95
+ // Fn extends (...args: any[]) => any,
96
+ // CurriedArgs extends Serializable[],
97
+ // AllArgs extends any[] = Parameters<Fn>,
98
+ // R = ReturnType<Fn>,
99
+ // DeferredArgs extends any[] = AllArgs extends [...infer D, ...CurriedArgs]
100
+ // ? D extends any[]
101
+ // ? D
102
+ // : never
103
+ // : never
104
+ // >(
105
+ // fn: (...args: [...DeferredArgs, ...CurriedArgs]) => R,
106
+ // ...curriedArgs: CurriedArgs
107
+ // ): Promise<Callback>;
108
+
109
+ /**
110
+ * Deletes a specific callback by its token.
111
+ *
112
+ * @param callback - The callback token to delete
113
+ * @returns Promise that resolves when the callback is deleted
114
+ */
115
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
116
+ abstract delete(callback: Callback): Promise<void>;
117
+
118
+ /**
119
+ * Deletes all callbacks for the tool's parent.
120
+ *
121
+ * @returns Promise that resolves when all callbacks are deleted
122
+ */
123
+ abstract deleteAll(): Promise<void>;
124
+
125
+ /**
126
+ * Executes a callback by its token.
127
+ *
128
+ * @param callback - The callback token returned by create()
129
+ * @param args - Optional arguments to pass to the callback function
130
+ * @returns Promise resolving to the callback result
131
+ */
132
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
133
+ abstract run<T = unknown>(callback: Callback, ...args: any[]): Promise<T>;
134
+ }
@@ -0,0 +1,266 @@
1
+ import { ITool } from "..";
2
+
3
+ /** Opaque session handle returned by connect(). */
4
+ export type ImapSession = string;
5
+
6
+ /** Credentials and server info for connecting to an IMAP server. */
7
+ export type ImapConnectOptions = {
8
+ /** IMAP server hostname (e.g. "imap.mail.me.com") */
9
+ host: string;
10
+ /** IMAP server port (e.g. 993 for TLS) */
11
+ port: number;
12
+ /** Whether to use TLS (true for port 993) */
13
+ tls: boolean;
14
+ /** IMAP username (typically the email address) */
15
+ username: string;
16
+ /** IMAP password (app-specific password for Apple) */
17
+ password: string;
18
+ };
19
+
20
+ /** A mailbox returned by listMailboxes(). */
21
+ export type ImapMailbox = {
22
+ /** Mailbox name (e.g. "INBOX", "Sent Messages") */
23
+ name: string;
24
+ /** Hierarchy delimiter (e.g. "/") */
25
+ delimiter: string;
26
+ /** Mailbox flags (e.g. ["\\HasNoChildren"]) */
27
+ flags: string[];
28
+ /** Special-use attribute if present (e.g. "\\Sent", "\\Drafts", "\\Trash") */
29
+ specialUse?: string;
30
+ };
31
+
32
+ /** Status of a selected mailbox. */
33
+ export type ImapMailboxStatus = {
34
+ /** Mailbox name */
35
+ name: string;
36
+ /** Total number of messages */
37
+ exists: number;
38
+ /** Number of recent messages */
39
+ recent: number;
40
+ /** UID validity value (changes if UIDs are reassigned) */
41
+ uidValidity: number;
42
+ /** Next UID to be assigned */
43
+ uidNext: number;
44
+ /** Number of unseen messages (may be absent) */
45
+ unseen?: number;
46
+ };
47
+
48
+ /** Criteria for searching messages. All fields are optional; they are ANDed together. */
49
+ export type ImapSearchCriteria = {
50
+ /** Messages with internal date on or after this date */
51
+ since?: Date | string;
52
+ /** Messages with internal date before this date */
53
+ before?: Date | string;
54
+ /** Messages with From header containing this string */
55
+ from?: string;
56
+ /** Messages with To header containing this string */
57
+ to?: string;
58
+ /** Messages with Subject containing this string */
59
+ subject?: string;
60
+ /** If true, only unseen messages; if false, only seen messages */
61
+ unseen?: boolean;
62
+ /** If true, only flagged messages; if false, only unflagged messages */
63
+ flagged?: boolean;
64
+ /** Specific UIDs to match */
65
+ uid?: number[];
66
+ };
67
+
68
+ /** An email address with optional display name. */
69
+ export type ImapAddress = {
70
+ /** Display name (e.g. "John Doe") */
71
+ name?: string;
72
+ /** Email address (e.g. "john@example.com") */
73
+ address: string;
74
+ };
75
+
76
+ /** A fetched message. Fields are populated based on ImapFetchOptions. */
77
+ export type ImapMessage = {
78
+ /** Message UID (stable across sessions if uidValidity hasn't changed) */
79
+ uid: number;
80
+ /** Message flags (e.g. ["\\Seen", "\\Flagged"]) */
81
+ flags: string[];
82
+ /** Internal date of the message */
83
+ date?: Date;
84
+ /** Subject header */
85
+ subject?: string;
86
+ /** From addresses */
87
+ from?: ImapAddress[];
88
+ /** To addresses */
89
+ to?: ImapAddress[];
90
+ /** CC addresses */
91
+ cc?: ImapAddress[];
92
+ /** Message-ID header */
93
+ messageId?: string;
94
+ /** In-Reply-To header (for threading) */
95
+ inReplyTo?: string;
96
+ /** References header (for threading) */
97
+ references?: string[];
98
+ /** Plain text body (when requested) */
99
+ bodyText?: string;
100
+ /** HTML body (when requested) */
101
+ bodyHtml?: string;
102
+ /** Message size in bytes */
103
+ size?: number;
104
+ };
105
+
106
+ /** Options for fetchMessages(). */
107
+ export type ImapFetchOptions = {
108
+ /** Fetch envelope/headers. Default: true. */
109
+ headers?: boolean;
110
+ /** Fetch body content. Default: false. */
111
+ body?: boolean;
112
+ /** Which body parts to fetch when body is true. Default: "both". */
113
+ bodyType?: "text" | "html" | "both";
114
+ };
115
+
116
+ /** How to modify flags. */
117
+ export type ImapFlagOperation = "add" | "remove" | "set";
118
+
119
+ /**
120
+ * Built-in tool for IMAP email access.
121
+ *
122
+ * Provides high-level IMAP operations for reading email and managing flags.
123
+ * Handles TCP/TLS connections, IMAP protocol details, and MIME decoding
124
+ * internally.
125
+ *
126
+ * **Permission model:** Connectors declare which IMAP hosts they need access
127
+ * to. Connections to undeclared hosts are rejected.
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * class AppleMailConnector extends Connector<AppleMailConnector> {
132
+ * build(build: ConnectorBuilder) {
133
+ * return {
134
+ * options: build(Options, {
135
+ * email: { type: "text", label: "Apple ID Email", default: "" },
136
+ * password: { type: "text", label: "App-Specific Password", secure: true, default: "" },
137
+ * }),
138
+ *
139
+ * imap: build(Imap, { hosts: ["imap.mail.me.com"] }),
140
+ * integrations: build(Integrations),
141
+ * };
142
+ * }
143
+ *
144
+ * async syncInbox() {
145
+ * const session = await this.tools.imap.connect({
146
+ * host: "imap.mail.me.com",
147
+ * port: 993,
148
+ * tls: true,
149
+ * username: this.tools.options.email,
150
+ * password: this.tools.options.password,
151
+ * });
152
+ *
153
+ * try {
154
+ * await this.tools.imap.selectMailbox(session, "INBOX");
155
+ * const uids = await this.tools.imap.search(session, { unseen: true });
156
+ * const messages = await this.tools.imap.fetchMessages(session, uids, {
157
+ * body: true,
158
+ * bodyType: "html",
159
+ * });
160
+ *
161
+ * for (const msg of messages) {
162
+ * await this.tools.integrations.saveLink({
163
+ * source: `apple-mail:${msg.messageId}`,
164
+ * title: msg.subject ?? "(no subject)",
165
+ * // ...
166
+ * });
167
+ * }
168
+ * } finally {
169
+ * await this.tools.imap.disconnect(session);
170
+ * }
171
+ * }
172
+ * }
173
+ * ```
174
+ */
175
+ export abstract class Imap extends ITool {
176
+ static readonly Options: {
177
+ /** IMAP server hostnames this tool is allowed to connect to. */
178
+ hosts: string[];
179
+ };
180
+
181
+ /**
182
+ * Opens a connection to an IMAP server and authenticates.
183
+ *
184
+ * @param options - Server address, port, TLS setting, and credentials
185
+ * @returns An opaque session handle for subsequent operations
186
+ * @throws If the host is not in the declared hosts list, connection fails, or auth fails
187
+ */
188
+ abstract connect(options: ImapConnectOptions): Promise<ImapSession>;
189
+
190
+ /**
191
+ * Lists all mailboxes (folders) on the server.
192
+ *
193
+ * @param session - Session handle from connect()
194
+ * @returns Array of mailbox descriptors
195
+ */
196
+ abstract listMailboxes(session: ImapSession): Promise<ImapMailbox[]>;
197
+
198
+ /**
199
+ * Selects a mailbox for subsequent search/fetch/flag operations.
200
+ *
201
+ * @param session - Session handle from connect()
202
+ * @param mailbox - Mailbox name (e.g. "INBOX")
203
+ * @returns Mailbox status including message count and UID validity
204
+ */
205
+ abstract selectMailbox(
206
+ session: ImapSession,
207
+ mailbox: string
208
+ ): Promise<ImapMailboxStatus>;
209
+
210
+ /**
211
+ * Searches for messages matching the given criteria in the selected mailbox.
212
+ *
213
+ * All criteria fields are ANDed together. Returns UIDs (not sequence numbers).
214
+ *
215
+ * @param session - Session handle from connect()
216
+ * @param criteria - Search criteria (all optional, ANDed)
217
+ * @returns Array of matching message UIDs
218
+ */
219
+ abstract search(
220
+ session: ImapSession,
221
+ criteria: ImapSearchCriteria
222
+ ): Promise<number[]>;
223
+
224
+ /**
225
+ * Fetches message data for the given UIDs.
226
+ *
227
+ * By default fetches headers only. Set `body: true` in options to include
228
+ * message body content. The implementation handles MIME decoding internally.
229
+ *
230
+ * @param session - Session handle from connect()
231
+ * @param uids - Array of message UIDs to fetch
232
+ * @param options - What to fetch (headers, body, body type)
233
+ * @returns Array of message objects with requested fields populated
234
+ */
235
+ abstract fetchMessages(
236
+ session: ImapSession,
237
+ uids: number[],
238
+ options?: ImapFetchOptions
239
+ ): Promise<ImapMessage[]>;
240
+
241
+ /**
242
+ * Modifies flags on messages.
243
+ *
244
+ * Common flags: "\\Seen" (read), "\\Flagged" (starred), "\\Deleted" (marked for deletion).
245
+ *
246
+ * @param session - Session handle from connect()
247
+ * @param uids - Array of message UIDs to modify
248
+ * @param flags - Flags to add/remove/set (e.g. ["\\Seen"])
249
+ * @param operation - "add", "remove", or "set" (replace all flags)
250
+ */
251
+ abstract setFlags(
252
+ session: ImapSession,
253
+ uids: number[],
254
+ flags: string[],
255
+ operation: ImapFlagOperation
256
+ ): Promise<void>;
257
+
258
+ /**
259
+ * Closes the IMAP connection.
260
+ *
261
+ * Always call this when done, preferably in a finally block.
262
+ *
263
+ * @param session - Session handle from connect()
264
+ */
265
+ abstract disconnect(session: ImapSession): Promise<void>;
266
+ }
@@ -0,0 +1,10 @@
1
+ export * from "./twists";
2
+ export * from "./ai";
3
+ export * from "./callbacks";
4
+ export * from "./integrations";
5
+ export * from "./network";
6
+ export * from "./plot";
7
+ export * from "./store";
8
+ export * from "./tasks";
9
+ export * from "./imap";
10
+ export * from "./smtp";