@plotday/twister 0.47.0 → 0.48.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 (72) hide show
  1. package/bin/commands/generate.js +5 -5
  2. package/bin/commands/generate.js.map +1 -1
  3. package/bin/utils/bundle.js +14 -0
  4. package/bin/utils/bundle.js.map +1 -1
  5. package/dist/docs/assets/hierarchy.js +1 -1
  6. package/dist/docs/assets/search.js +1 -1
  7. package/dist/docs/classes/index.Connector.html +1 -1
  8. package/dist/docs/classes/index.Imap.html +1 -1
  9. package/dist/docs/classes/index.Options.html +1 -1
  10. package/dist/docs/classes/index.Smtp.html +1 -1
  11. package/dist/docs/classes/tools_network.Network.html +1 -1
  12. package/dist/docs/classes/tools_plot.Plot.html +1 -1
  13. package/dist/docs/classes/tools_store.Store.html +1 -1
  14. package/dist/docs/classes/tools_tasks.Tasks.html +1 -1
  15. package/dist/docs/documents/CLI_Reference.html +6 -4
  16. package/dist/docs/enums/tools_integrations.AuthProvider.html +3 -1
  17. package/dist/docs/hierarchy.html +1 -1
  18. package/dist/docs/types/tools_integrations.AuthToken.html +4 -4
  19. package/dist/docs/types/tools_integrations.Authorization.html +4 -4
  20. package/dist/llm-docs/tools/integrations.d.ts +1 -1
  21. package/dist/llm-docs/tools/integrations.d.ts.map +1 -1
  22. package/dist/llm-docs/tools/integrations.js +1 -1
  23. package/dist/llm-docs/tools/integrations.js.map +1 -1
  24. package/dist/tools/integrations.d.ts +3 -1
  25. package/dist/tools/integrations.d.ts.map +1 -1
  26. package/dist/tools/integrations.js +2 -0
  27. package/dist/tools/integrations.js.map +1 -1
  28. package/package.json +2 -1
  29. package/src/connector.ts +366 -0
  30. package/src/creator-docs.ts +29 -0
  31. package/src/index.ts +10 -0
  32. package/src/llm-docs/connector.ts +8 -0
  33. package/src/llm-docs/index.ts +48 -0
  34. package/src/llm-docs/options.ts +8 -0
  35. package/src/llm-docs/plot.ts +8 -0
  36. package/src/llm-docs/schedule.ts +8 -0
  37. package/src/llm-docs/tag.ts +8 -0
  38. package/src/llm-docs/tool.ts +8 -0
  39. package/src/llm-docs/tools/ai.ts +8 -0
  40. package/src/llm-docs/tools/callbacks.ts +8 -0
  41. package/src/llm-docs/tools/imap.ts +8 -0
  42. package/src/llm-docs/tools/integrations.ts +8 -0
  43. package/src/llm-docs/tools/network.ts +8 -0
  44. package/src/llm-docs/tools/plot.ts +8 -0
  45. package/src/llm-docs/tools/smtp.ts +8 -0
  46. package/src/llm-docs/tools/store.ts +8 -0
  47. package/src/llm-docs/tools/tasks.ts +8 -0
  48. package/src/llm-docs/tools/twists.ts +8 -0
  49. package/src/llm-docs/twist-guide-template.ts +8 -0
  50. package/src/llm-docs/twist.ts +8 -0
  51. package/src/options.ts +115 -0
  52. package/src/plot.ts +1068 -0
  53. package/src/schedule.ts +203 -0
  54. package/src/tag.ts +44 -0
  55. package/src/tool.ts +377 -0
  56. package/src/tools/ai.ts +845 -0
  57. package/src/tools/callbacks.ts +134 -0
  58. package/src/tools/imap.ts +266 -0
  59. package/src/tools/index.ts +10 -0
  60. package/src/tools/integrations.ts +328 -0
  61. package/src/tools/network.ts +240 -0
  62. package/src/tools/plot.ts +692 -0
  63. package/src/tools/smtp.ts +166 -0
  64. package/src/tools/store.ts +149 -0
  65. package/src/tools/tasks.ts +137 -0
  66. package/src/tools/twists.ts +228 -0
  67. package/src/twist-guide.ts +9 -0
  68. package/src/twist.ts +435 -0
  69. package/src/utils/hash.ts +8 -0
  70. package/src/utils/serializable.ts +54 -0
  71. package/src/utils/types.ts +130 -0
  72. package/src/utils/uuid.ts +9 -0
@@ -0,0 +1,692 @@
1
+ import {
2
+ type Action,
3
+ type Thread,
4
+ type ThreadUpdate,
5
+ type Actor,
6
+ type ActorId,
7
+ ITool,
8
+ type Link,
9
+ type LinkUpdate,
10
+ type NewThread,
11
+ type NewThreadWithNotes,
12
+ type NewNote,
13
+ type NewPriority,
14
+ type Note,
15
+ type NoteUpdate,
16
+ type PlanOperation,
17
+ type Priority,
18
+ type PriorityUpdate,
19
+ Uuid,
20
+ } from "..";
21
+ import {
22
+ type Schedule,
23
+ type NewSchedule,
24
+ } from "../schedule";
25
+ import type { Callback } from "./callbacks";
26
+
27
+ export enum ThreadAccess {
28
+ /**
29
+ * Create new Note on a Thread where the twist was mentioned.
30
+ * Add/remove tags on Thread or Note where the twist was mentioned.
31
+ */
32
+ Respond,
33
+ /**
34
+ * Create new Thread.
35
+ * Create new Note in a Thread the twist created.
36
+ * All Respond permissions.
37
+ */
38
+ Create,
39
+ /**
40
+ * List/query all Threads owned by the twist's user.
41
+ * Update any Thread (title, tags, archived, type, priority) regardless of creator.
42
+ * Create Notes on any Thread (not just own or mentioned).
43
+ * All Create permissions.
44
+ */
45
+ Full,
46
+ }
47
+
48
+ export enum PriorityAccess {
49
+ /**
50
+ * Create new Priorities under the twist owner's priority tree.
51
+ * Update Priorities created by the twist.
52
+ */
53
+ Create,
54
+ /**
55
+ * Read all Priorities owned by the twist's user.
56
+ * Create new Priorities under the twist owner's priority tree.
57
+ * Update and archive any Priority owned by the twist's user.
58
+ */
59
+ Full,
60
+ }
61
+
62
+ export enum ContactAccess {
63
+ /** Read existing contact details. Without this, only the ID will be provided. */
64
+ Read,
65
+ }
66
+
67
+ export enum LinkAccess {
68
+ /** Read links on any thread owned by the twist's user. */
69
+ Read,
70
+ /** Read + update links, including moving links between threads owned by the twist's user. */
71
+ Full,
72
+ }
73
+
74
+ /**
75
+ * Intent handler for thread mentions.
76
+ * Defines how the twist should respond when mentioned in a thread.
77
+ */
78
+ export type NoteIntentHandler = {
79
+ /** Human-readable description of what this intent handles */
80
+ description: string;
81
+ /** Example phrases or activity content that would match this intent */
82
+ examples: string[];
83
+ /** The function to call when this intent is matched */
84
+ handler: (note: Note) => Promise<void>;
85
+ };
86
+
87
+ /**
88
+ * Filter for querying links from connected source channels.
89
+ */
90
+ export type LinkFilter = {
91
+ /** Only return links from these channel IDs. */
92
+ channelIds?: string[];
93
+ /** Only return links created/updated after this date. */
94
+ since?: Date;
95
+ /** Only return links of this type. */
96
+ type?: string;
97
+ /** Maximum number of links to return. */
98
+ limit?: number;
99
+ };
100
+
101
+ type SearchResultBase = {
102
+ thread: { id: string; title: string | null };
103
+ priority: { id: string; title: string | null };
104
+ similarity: number;
105
+ };
106
+
107
+ export type NoteSearchResult = SearchResultBase & {
108
+ type: 'note';
109
+ id: string;
110
+ content: string | null;
111
+ };
112
+
113
+ export type LinkSearchResult = SearchResultBase & {
114
+ type: 'link';
115
+ id: string;
116
+ title: string | null;
117
+ sourceUrl: string | null;
118
+ content: string | null;
119
+ };
120
+
121
+ export type SearchResult = NoteSearchResult | LinkSearchResult;
122
+
123
+ /** Default number of search results returned */
124
+ export const SEARCH_DEFAULT_LIMIT = 10;
125
+ /** Maximum number of search results allowed */
126
+ export const SEARCH_MAX_LIMIT = 30;
127
+
128
+ export type SearchOptions = {
129
+ /** Max results to return (default: 10, max: 30) */
130
+ limit?: number;
131
+ /** Minimum similarity score 0-1 (default: 0.3) */
132
+ threshold?: number;
133
+ /**
134
+ * Scope search to this priority + descendants. Must be owned by the twist
135
+ * owner. When omitted, the server scopes the search to the owner's entire
136
+ * priority tree.
137
+ */
138
+ priorityId?: string;
139
+ };
140
+
141
+ /**
142
+ * Built-in tool for interacting with the core Plot data layer.
143
+ *
144
+ * The Plot tool provides twists with the ability to create and manage threads,
145
+ * priorities, and contacts within the Plot system. This is the primary interface
146
+ * for twists to persist data and interact with the Plot database.
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * class MyTwist extends Twist {
151
+ * private plot: Plot;
152
+ *
153
+ * constructor(id: string, tools: ToolBuilder) {
154
+ * super();
155
+ * this.plot = tools.get(Plot);
156
+ * }
157
+ *
158
+ * async activate() {
159
+ * // Create a welcome thread
160
+ * await this.plot.createThread({
161
+ * title: "Welcome to Plot!",
162
+ * actions: [{
163
+ * title: "Get Started",
164
+ * type: ActionType.external,
165
+ * url: "https://plot.day/docs"
166
+ * }]
167
+ * });
168
+ * }
169
+ * }
170
+ * ```
171
+ */
172
+ export abstract class Plot extends ITool {
173
+ /**
174
+ * Configuration options for the Plot tool.
175
+ *
176
+ * **Important**: All permissions must be explicitly requested. There are no default permissions.
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * // Minimal configuration with required permissions
181
+ * build(build: ToolBuilder) {
182
+ * return {
183
+ * plot: build(Plot, {
184
+ * thread: {
185
+ * access: ThreadAccess.Create
186
+ * }
187
+ * })
188
+ * };
189
+ * }
190
+ *
191
+ * // Full configuration with callbacks
192
+ * build(build: ToolBuilder) {
193
+ * return {
194
+ * plot: build(Plot, {
195
+ * thread: {
196
+ * access: ThreadAccess.Create,
197
+ * },
198
+ * note: {
199
+ * intents: [{
200
+ * description: "Schedule meetings",
201
+ * examples: ["Schedule a meeting tomorrow"],
202
+ * handler: this.onSchedulingIntent
203
+ * }],
204
+ * },
205
+ * link: true,
206
+ * priority: {
207
+ * access: PriorityAccess.Full
208
+ * },
209
+ * contact: {
210
+ * access: ContactAccess.Read
211
+ * }
212
+ * })
213
+ * };
214
+ * }
215
+ * ```
216
+ */
217
+ static readonly Options: {
218
+ thread?: {
219
+ /**
220
+ * Capability to create Notes and modify tags.
221
+ * Must be explicitly set to grant permissions.
222
+ */
223
+ access?: ThreadAccess;
224
+ /** When true, auto-mention this twist on new notes in threads where it authored content. */
225
+ defaultMention?: boolean;
226
+ };
227
+ note?: {
228
+ /** When true, auto-mention this twist on new notes in threads where it was @-mentioned. */
229
+ defaultMention?: boolean;
230
+ /**
231
+ * Respond to mentions in notes.
232
+ *
233
+ * When a note mentions this twist, the system will match the note
234
+ * content against these intents and call the matching handler.
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * intents: [{
239
+ * description: "Schedule or reschedule calendar events",
240
+ * examples: ["Schedule a meeting tomorrow at 2pm", "Move my 3pm meeting to 4pm"],
241
+ * handler: this.onSchedulingRequest
242
+ * }, {
243
+ * description: "Find available meeting times",
244
+ * examples: ["When am I free this week?", "Find time for a 1 hour meeting"],
245
+ * handler: this.onAvailabilityRequest
246
+ * }]
247
+ * ```
248
+ */
249
+ intents?: NoteIntentHandler[];
250
+ };
251
+ /** Enable link processing from connected source channels. */
252
+ link?: true | {
253
+ /** Access level for links. When omitted with `link: true`, only source channel links are accessible. */
254
+ access?: LinkAccess;
255
+ };
256
+ priority?: {
257
+ access?: PriorityAccess;
258
+ };
259
+ contact?: {
260
+ access?: ContactAccess;
261
+ };
262
+ /** Enable semantic search across notes and links owned by the twist's user. */
263
+ search?: true;
264
+ /**
265
+ * When true, admin write operations (on threads/notes/links/priorities not created by this twist)
266
+ * require user approval via plan actions instead of executing immediately.
267
+ * Read operations and operations on the twist's own content still work directly.
268
+ */
269
+ requireApproval?: boolean;
270
+ };
271
+
272
+ /**
273
+ * Creates a new thread in the Plot system.
274
+ *
275
+ * The thread will be automatically assigned an ID and author information
276
+ * based on the current execution context. All other fields from NewThread
277
+ * will be preserved in the created thread.
278
+ *
279
+ * @param thread - The thread data to create
280
+ * @returns Promise resolving to the created thread's ID
281
+ */
282
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
283
+ abstract createThread(
284
+ thread: NewThread | NewThreadWithNotes
285
+ ): Promise<Uuid>;
286
+
287
+ /**
288
+ * Creates multiple threads in a single batch operation.
289
+ *
290
+ * This method efficiently creates multiple threads at once, which is
291
+ * more performant than calling createThread() multiple times individually.
292
+ * All threads are created with the same author and access control rules.
293
+ *
294
+ * @param threads - Array of thread data to create
295
+ * @returns Promise resolving to array of created thread IDs
296
+ */
297
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
298
+ abstract createThreads(
299
+ threads: (NewThread | NewThreadWithNotes)[]
300
+ ): Promise<Uuid[]>;
301
+
302
+ /**
303
+ * Updates an existing thread in the Plot system.
304
+ *
305
+ * **Important**: This method only updates existing threads. It will throw an error
306
+ * if the thread does not exist. Use `createThread()` to create or update (upsert)
307
+ * threads.
308
+ *
309
+ * Only the fields provided in the update object will be modified - all other fields
310
+ * remain unchanged. This enables partial updates without needing to fetch and resend
311
+ * the entire thread object.
312
+ *
313
+ * For tags, provide a Record<number, boolean> where true adds a tag and false removes it.
314
+ * Tags not included in the update remain unchanged.
315
+ *
316
+ * When updating the parent, the thread's path will be automatically recalculated to
317
+ * maintain the correct hierarchical structure.
318
+ *
319
+ * Scheduling is handled separately via `createSchedule()` / `updateSchedule()`.
320
+ *
321
+ * @param thread - The thread update containing the ID or source and fields to change
322
+ * @returns Promise that resolves when the update is complete
323
+ * @throws Error if the thread does not exist
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * // Mark a task as complete
328
+ * await this.plot.updateThread({
329
+ * id: "task-123",
330
+ * done: new Date()
331
+ * });
332
+ *
333
+ * // Add and remove tags
334
+ * await this.plot.updateThread({
335
+ * id: "thread-789",
336
+ * tags: {
337
+ * 1: true, // Add tag with ID 1
338
+ * 2: false // Remove tag with ID 2
339
+ * }
340
+ * });
341
+ * ```
342
+ */
343
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
344
+ abstract updateThread(thread: ThreadUpdate): Promise<void>;
345
+
346
+ /**
347
+ * Retrieves all notes within a thread.
348
+ *
349
+ * Notes are detailed entries within a thread, ordered by creation time.
350
+ * Each note can contain markdown content, actions, and other detailed information
351
+ * related to the parent thread.
352
+ *
353
+ * @param thread - The thread whose notes to retrieve
354
+ * @returns Promise resolving to array of notes in the thread
355
+ */
356
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
357
+ abstract getNotes(thread: Thread): Promise<Note[]>;
358
+
359
+ /**
360
+ * Creates a new note in a thread.
361
+ *
362
+ * Notes provide detailed content within a thread, supporting markdown,
363
+ * actions, and other rich content. The note will be automatically assigned
364
+ * an ID and author information based on the current execution context.
365
+ *
366
+ * @param note - The note data to create
367
+ * @returns Promise resolving to the created note's ID
368
+ *
369
+ * @example
370
+ * ```typescript
371
+ * // Create a note with content
372
+ * await this.plot.createNote({
373
+ * thread: { id: "thread-123" },
374
+ * note: "Discussion notes from the meeting...",
375
+ * contentType: "markdown"
376
+ * });
377
+ *
378
+ * // Create a note with actions
379
+ * await this.plot.createNote({
380
+ * thread: { id: "thread-456" },
381
+ * note: "Meeting recording available",
382
+ * actions: [{
383
+ * type: ActionType.external,
384
+ * title: "View Recording",
385
+ * url: "https://example.com/recording"
386
+ * }]
387
+ * });
388
+ * ```
389
+ */
390
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
391
+ abstract createNote(note: NewNote): Promise<Uuid>;
392
+
393
+ /**
394
+ * Creates multiple notes in a single batch operation.
395
+ *
396
+ * This method efficiently creates multiple notes at once, which is
397
+ * more performant than calling createNote() multiple times individually.
398
+ * All notes are created with the same author and access control rules.
399
+ *
400
+ * @param notes - Array of note data to create
401
+ * @returns Promise resolving to array of created note IDs
402
+ *
403
+ * @example
404
+ * ```typescript
405
+ * // Create multiple notes in one batch
406
+ * await this.plot.createNotes([
407
+ * {
408
+ * thread: { id: "thread-123" },
409
+ * note: "First message in thread"
410
+ * },
411
+ * {
412
+ * thread: { id: "thread-123" },
413
+ * note: "Second message in thread"
414
+ * }
415
+ * ]);
416
+ * ```
417
+ */
418
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
419
+ abstract createNotes(notes: NewNote[]): Promise<Uuid[]>;
420
+
421
+ /**
422
+ * Updates an existing note in the Plot system.
423
+ *
424
+ * **Important**: This method only updates existing notes. It will throw an error
425
+ * if the note does not exist. Use `createNote()` to create or update (upsert) notes.
426
+ *
427
+ * Only the fields provided in the update object will be modified - all other fields
428
+ * remain unchanged. This enables partial updates without needing to fetch and resend
429
+ * the entire note object.
430
+ *
431
+ * @param note - The note update containing the ID or key and fields to change
432
+ * @returns Promise that resolves when the update is complete
433
+ * @throws Error if the note does not exist
434
+ *
435
+ * @example
436
+ * ```typescript
437
+ * // Update note content
438
+ * await this.plot.updateNote({
439
+ * id: "note-123",
440
+ * note: "Updated content with more details"
441
+ * });
442
+ *
443
+ * // Add tags to a note
444
+ * await this.plot.updateNote({
445
+ * id: "note-456",
446
+ * twistTags: {
447
+ * [Tag.Important]: true
448
+ * }
449
+ * });
450
+ * ```
451
+ */
452
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
453
+ abstract updateNote(note: NoteUpdate): Promise<void>;
454
+
455
+ /**
456
+ * Retrieves a thread by ID or source.
457
+ *
458
+ * This method enables lookup of threads either by their unique ID or by their
459
+ * source identifier (canonical URL from an external system). Archived threads
460
+ * are included in the results.
461
+ *
462
+ * @param thread - Thread lookup by ID or source
463
+ * @returns Promise resolving to the matching thread or null if not found
464
+ */
465
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
466
+ abstract getThread(
467
+ thread: { id: Uuid } | { source: string }
468
+ ): Promise<Thread | null>;
469
+
470
+ /**
471
+ * Retrieves a note by ID or key.
472
+ *
473
+ * This method enables lookup of notes either by their unique ID or by their
474
+ * key (unique identifier within the thread). Archived notes are included
475
+ * in the results.
476
+ *
477
+ * @param note - Note lookup by ID or key
478
+ * @returns Promise resolving to the matching note or null if not found
479
+ */
480
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
481
+ abstract getNote(note: { id: Uuid } | { key: string }): Promise<Note | null>;
482
+
483
+ /**
484
+ * Creates a new priority in the Plot system.
485
+ *
486
+ * Priorities serve as organizational containers for threads and twists.
487
+ * The created priority will be automatically assigned a unique ID.
488
+ *
489
+ * @param priority - The priority data to create
490
+ * @returns Promise resolving to the complete created priority
491
+ */
492
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
493
+ abstract createPriority(priority: NewPriority): Promise<Priority & { created: boolean }>;
494
+
495
+ /**
496
+ * Retrieves a priority by ID or key.
497
+ *
498
+ * Archived priorities are included in the results.
499
+ *
500
+ * @param priority - Priority lookup by ID or key
501
+ * @returns Promise resolving to the matching priority or null if not found
502
+ */
503
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
504
+ abstract getPriority(
505
+ priority: { id: Uuid } | { key: string }
506
+ ): Promise<Priority | null>;
507
+
508
+ /**
509
+ * Updates an existing priority in the Plot system.
510
+ *
511
+ * The priority is identified by either its ID or key.
512
+ * Only the fields specified in the update will be changed.
513
+ *
514
+ * @param update - Priority update containing ID/key and fields to change
515
+ * @returns Promise that resolves when the update is complete
516
+ */
517
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
518
+ abstract updatePriority(update: PriorityUpdate): Promise<void>;
519
+
520
+ /**
521
+ * Retrieves actors by their IDs.
522
+ *
523
+ * Actors represent users, contacts, or twists in the Plot system.
524
+ * This method requires ContactAccess.Read permission.
525
+ *
526
+ * @param ids - Array of actor IDs to retrieve
527
+ * @returns Promise resolving to array of actors
528
+ */
529
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
530
+ abstract getActors(ids: ActorId[]): Promise<Actor[]>;
531
+
532
+ /**
533
+ * Returns the full Actor for the user who installed this twist.
534
+ * Useful for per-user operations like schedule creation, or when
535
+ * the owner's name or email is needed.
536
+ */
537
+ abstract getOwner(): Promise<Actor>;
538
+
539
+ /**
540
+ * Returns the user ID (`twist_instance.owner_id`) that installed this
541
+ * twist. This is the same value exposed on Twist via `this.userId`.
542
+ */
543
+ abstract getUserId(): Promise<string>;
544
+
545
+ /**
546
+ * Returns the owner user's root priority ID. Used as the implicit default
547
+ * when an operation needs a priority but the caller didn't supply one —
548
+ * for example, `plot.createPriority()` without a parent, or
549
+ * `plot.getThreads()` without an explicit `priorityId`.
550
+ *
551
+ * On the server, priority resolution for newly created threads/links
552
+ * happens automatically via `match_priority_for_user`; twists rarely need
553
+ * to call this directly.
554
+ */
555
+ abstract getDefaultPriorityId(): Promise<string>;
556
+
557
+ /**
558
+ * Creates a new schedule for a thread.
559
+ *
560
+ * Schedules define when a thread occurs in time. A thread can have
561
+ * multiple schedules (shared and per-user).
562
+ *
563
+ * @param schedule - The schedule data to create
564
+ * @returns Promise resolving to the created schedule
565
+ *
566
+ * @example
567
+ * ```typescript
568
+ * // Schedule a timed event
569
+ * const threadId = await this.plot.createThread({
570
+ * title: "Team standup"
571
+ * });
572
+ * await this.plot.createSchedule({
573
+ * threadId,
574
+ * start: new Date("2025-01-15T10:00:00Z"),
575
+ * end: new Date("2025-01-15T10:30:00Z"),
576
+ * recurrenceRule: "FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR"
577
+ * });
578
+ * ```
579
+ */
580
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
581
+ abstract createSchedule(schedule: NewSchedule): Promise<Schedule>;
582
+
583
+ /**
584
+ * Retrieves all schedules for a thread.
585
+ *
586
+ * @param threadId - The thread whose schedules to retrieve
587
+ * @returns Promise resolving to array of schedules for the thread
588
+ */
589
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
590
+ abstract getSchedules(threadId: Uuid): Promise<Schedule[]>;
591
+
592
+ /**
593
+ * Retrieves links from connected source channels.
594
+ *
595
+ * Requires `link: true` in Plot options.
596
+ *
597
+ * @param filter - Optional filter criteria for links
598
+ * @returns Promise resolving to array of links with their notes
599
+ */
600
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
601
+ abstract getLinks(filter?: LinkFilter): Promise<Array<{ link: Link; notes: Note[] }>>;
602
+
603
+ /**
604
+ * Searches notes and links using semantic similarity.
605
+ *
606
+ * Requires `search: true` in Plot options.
607
+ *
608
+ * @param query - The search query text
609
+ * @param options - Optional search configuration
610
+ * @returns Promise resolving to array of search results ordered by similarity
611
+ */
612
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
613
+ abstract search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
614
+
615
+ /**
616
+ * Lists threads owned by the twist's user.
617
+ *
618
+ * Requires `ThreadAccess.Full`.
619
+ *
620
+ * @param options - Query options for filtering threads
621
+ * @returns Promise resolving to array of threads
622
+ */
623
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
624
+ abstract getThreads(options?: {
625
+ /**
626
+ * Priority to list threads from. Must be owned by the twist owner.
627
+ * When omitted, defaults to the owner's root priority.
628
+ */
629
+ priorityId?: Uuid;
630
+ /** Include threads from descendant priorities. Default: true. */
631
+ includeDescendants?: boolean;
632
+ /** Include archived threads. Default: false. */
633
+ includeArchived?: boolean;
634
+ /** Maximum number of threads to return. Default: 50, max: 200. */
635
+ limit?: number;
636
+ /** Number of threads to skip for pagination. Default: 0. */
637
+ offset?: number;
638
+ }): Promise<Thread[]>;
639
+
640
+ /**
641
+ * Lists priorities owned by the twist's user.
642
+ *
643
+ * Requires `PriorityAccess.Full`.
644
+ *
645
+ * @param options - Query options for filtering priorities
646
+ * @returns Promise resolving to array of priorities
647
+ */
648
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
649
+ abstract getPriorities(options?: {
650
+ /**
651
+ * Parent priority to list children of. Must be owned by the twist
652
+ * owner. When omitted, defaults to the owner's root priority.
653
+ */
654
+ parentId?: Uuid;
655
+ /** Include all descendants, not just direct children. Default: false. */
656
+ includeDescendants?: boolean;
657
+ /** Include archived priorities. Default: false. */
658
+ includeArchived?: boolean;
659
+ }): Promise<Priority[]>;
660
+
661
+ /**
662
+ * Updates a link.
663
+ *
664
+ * Requires `LinkAccess.Full`. Set `threadId` to move the link to a different thread.
665
+ *
666
+ * @param link - The link update containing the ID and fields to change
667
+ * @returns Promise that resolves when the update is complete
668
+ */
669
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
670
+ abstract updateLink(link: LinkUpdate): Promise<void>;
671
+
672
+ /**
673
+ * Creates a plan of operations for user approval.
674
+ *
675
+ * Returns an Action that can be attached to a note. The user can approve,
676
+ * deny, or request changes. On approval, operations are executed by the API.
677
+ *
678
+ * Requires `requireApproval: true` in Plot options.
679
+ *
680
+ * @param options - Plan configuration
681
+ * @returns An Action of type `plan` to attach to a note
682
+ */
683
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
684
+ abstract createPlan(options: {
685
+ /** Human-readable title summarizing the plan */
686
+ title: string;
687
+ /** Array of operations to execute on approval */
688
+ operations: PlanOperation[];
689
+ /** Callback invoked with (action, approved: boolean) when the user responds */
690
+ callback: Callback;
691
+ }): Action;
692
+ }