@plotday/twister 0.49.0 → 0.51.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 (90) hide show
  1. package/dist/connector.d.ts +30 -3
  2. package/dist/connector.d.ts.map +1 -1
  3. package/dist/connector.js.map +1 -1
  4. package/dist/docs/assets/hierarchy.js +1 -1
  5. package/dist/docs/assets/search.js +1 -1
  6. package/dist/docs/classes/index.Connector.html +37 -13
  7. package/dist/docs/classes/index.Imap.html +1 -1
  8. package/dist/docs/classes/index.Options.html +1 -1
  9. package/dist/docs/classes/index.Smtp.html +1 -1
  10. package/dist/docs/classes/tools_integrations.Integrations.html +40 -10
  11. package/dist/docs/classes/tools_network.Network.html +1 -1
  12. package/dist/docs/classes/tools_plot.Plot.html +11 -19
  13. package/dist/docs/classes/tools_store.Store.html +25 -2
  14. package/dist/docs/classes/tools_tasks.Tasks.html +1 -1
  15. package/dist/docs/documents/Built-in_Tools.html +1 -1
  16. package/dist/docs/documents/Runtime_Environment.html +25 -1
  17. package/dist/docs/enums/plot.ActorType.html +4 -4
  18. package/dist/docs/enums/tools_integrations.AuthProvider.html +13 -13
  19. package/dist/docs/hierarchy.html +1 -1
  20. package/dist/docs/types/index.NewScheduleOccurrence.html +15 -2
  21. package/dist/docs/types/index.ScheduleOccurrence.html +2 -4
  22. package/dist/docs/types/index.ScheduleOccurrenceUpdate.html +1 -1
  23. package/dist/docs/types/plot.Actor.html +5 -5
  24. package/dist/docs/types/plot.Contact.html +4 -4
  25. package/dist/docs/types/plot.ContentType.html +1 -1
  26. package/dist/docs/types/plot.Link.html +24 -19
  27. package/dist/docs/types/plot.LinkUpdate.html +1 -1
  28. package/dist/docs/types/plot.NewActor.html +1 -1
  29. package/dist/docs/types/plot.NewContact.html +1 -1
  30. package/dist/docs/types/plot.NewLink.html +11 -4
  31. package/dist/docs/types/plot.NewLinkWithNotes.html +1 -1
  32. package/dist/docs/types/plot.NewNote.html +1 -1
  33. package/dist/docs/types/plot.Note.html +7 -1
  34. package/dist/docs/types/plot.NoteUpdate.html +1 -1
  35. package/dist/docs/types/plot.PlanOperation.html +1 -1
  36. package/dist/docs/types/tools_integrations.ArchiveLinkFilter.html +5 -5
  37. package/dist/docs/types/tools_integrations.AuthToken.html +4 -4
  38. package/dist/docs/types/tools_integrations.Authorization.html +4 -4
  39. package/dist/docs/types/tools_integrations.SyncContext.html +21 -2
  40. package/dist/llm-docs/connector.d.ts +1 -1
  41. package/dist/llm-docs/connector.d.ts.map +1 -1
  42. package/dist/llm-docs/connector.js +1 -1
  43. package/dist/llm-docs/connector.js.map +1 -1
  44. package/dist/llm-docs/plot.d.ts +1 -1
  45. package/dist/llm-docs/plot.d.ts.map +1 -1
  46. package/dist/llm-docs/plot.js +1 -1
  47. package/dist/llm-docs/plot.js.map +1 -1
  48. package/dist/llm-docs/schedule.d.ts +1 -1
  49. package/dist/llm-docs/schedule.d.ts.map +1 -1
  50. package/dist/llm-docs/schedule.js +1 -1
  51. package/dist/llm-docs/schedule.js.map +1 -1
  52. package/dist/llm-docs/tools/integrations.d.ts +1 -1
  53. package/dist/llm-docs/tools/integrations.d.ts.map +1 -1
  54. package/dist/llm-docs/tools/integrations.js +1 -1
  55. package/dist/llm-docs/tools/integrations.js.map +1 -1
  56. package/dist/llm-docs/tools/plot.d.ts +1 -1
  57. package/dist/llm-docs/tools/plot.d.ts.map +1 -1
  58. package/dist/llm-docs/tools/plot.js +1 -1
  59. package/dist/llm-docs/tools/plot.js.map +1 -1
  60. package/dist/llm-docs/tools/store.d.ts +1 -1
  61. package/dist/llm-docs/tools/store.d.ts.map +1 -1
  62. package/dist/llm-docs/tools/store.js +1 -1
  63. package/dist/llm-docs/tools/store.js.map +1 -1
  64. package/dist/plot.d.ts +33 -7
  65. package/dist/plot.d.ts.map +1 -1
  66. package/dist/plot.js.map +1 -1
  67. package/dist/schedule.d.ts +18 -2
  68. package/dist/schedule.d.ts.map +1 -1
  69. package/dist/tools/integrations.d.ts +64 -0
  70. package/dist/tools/integrations.d.ts.map +1 -1
  71. package/dist/tools/integrations.js.map +1 -1
  72. package/dist/tools/plot.d.ts +0 -11
  73. package/dist/tools/plot.d.ts.map +1 -1
  74. package/dist/tools/plot.js.map +1 -1
  75. package/dist/tools/store.d.ts +40 -0
  76. package/dist/tools/store.d.ts.map +1 -1
  77. package/dist/tools/store.js.map +1 -1
  78. package/package.json +1 -1
  79. package/src/connector.ts +30 -3
  80. package/src/llm-docs/connector.ts +1 -1
  81. package/src/llm-docs/plot.ts +1 -1
  82. package/src/llm-docs/schedule.ts +1 -1
  83. package/src/llm-docs/tools/integrations.ts +1 -1
  84. package/src/llm-docs/tools/plot.ts +1 -1
  85. package/src/llm-docs/tools/store.ts +1 -1
  86. package/src/plot.ts +40 -16
  87. package/src/schedule.ts +19 -3
  88. package/src/tools/integrations.ts +69 -0
  89. package/src/tools/plot.ts +0 -12
  90. package/src/tools/store.ts +44 -0
@@ -88,6 +88,29 @@ export type SyncContext = {
88
88
  * Undefined when no limit applies.
89
89
  */
90
90
  syncHistoryMin?: Date;
91
+
92
+ /**
93
+ * True when this is a recovery dispatch after the connection's auth was
94
+ * restored (the user re-authorized a previously-broken connection).
95
+ *
96
+ * The framework calls `onChannelEnabled` again for every channel that was
97
+ * already enabled at the time of re-auth so the connector can recover from
98
+ * the auth gap. Connectors should:
99
+ *
100
+ * 1. Drop any persisted incremental sync cursors / sync tokens so the
101
+ * next sync re-walks history (the cursor may be stale or invalid —
102
+ * Google Calendar invalidates syncTokens after ~7 days).
103
+ * 2. Re-register webhooks (any prior subscription may have been
104
+ * invalidated during the auth outage).
105
+ * 3. Treat this as a backfill that walks history but does NOT spam
106
+ * notifications — set `unread: false` and `archived: false` on
107
+ * items as you would during initial sync.
108
+ *
109
+ * Most connectors can take the same code path as a fresh
110
+ * `onChannelEnabled` for `recovering: true` as long as that path
111
+ * overwrites stored state rather than appending to it.
112
+ */
113
+ recovering?: boolean;
91
114
  };
92
115
 
93
116
  /**
@@ -264,6 +287,52 @@ export abstract class Integrations extends ITool {
264
287
  options?: { date?: Date | string }
265
288
  ): Promise<void>;
266
289
 
290
+ /**
291
+ * Signal that initial bulk-sync (or recovery sync) for a channel is fully
292
+ * complete. The Flutter app uses this to clear the "syncing…" indicator
293
+ * on the connection.
294
+ *
295
+ * The framework automatically marks a channel as syncing when it dispatches
296
+ * `onChannelEnabled` (whether initial-enable, auto-enable from
297
+ * `setChannels`, or recovery after re-auth). Connectors do NOT need to
298
+ * call anything to start tracking — only to signal completion.
299
+ *
300
+ * Call this exactly once when the initial backfill has finished (no more
301
+ * pages, all phases exhausted). Do NOT call it on every incremental sync.
302
+ *
303
+ * If `onChannelEnabled` throws an unhandled exception, the framework
304
+ * automatically clears the syncing state — connectors don't need a
305
+ * `try/catch` to clear state on failure.
306
+ *
307
+ * No-op when no auth/user mapping exists for the channel (e.g. key-based
308
+ * connectors that don't have a per-user OAuth association).
309
+ *
310
+ * @param channelId - The channel resource ID whose initial sync just finished
311
+ */
312
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
313
+ abstract channelSyncCompleted(channelId: string): Promise<void>;
314
+
315
+ /**
316
+ * Flag a connection as needing re-authentication so the Flutter app
317
+ * surfaces a re-auth prompt on the next sync.
318
+ *
319
+ * Call this when a connector's API call returns a permanent auth-style
320
+ * error that the runtime can't observe through token refresh — e.g.
321
+ * Slack `invalid_auth` / `token_revoked` / `not_authed`, or a 401 on a
322
+ * provider that doesn't refresh. The runtime already flags reauth
323
+ * automatically when an OAuth refresh permanently fails or when the
324
+ * stored token is missing on a get(); only call this for cases the
325
+ * runtime can't see.
326
+ *
327
+ * Idempotent: safe to call repeatedly; existing reauth flags are not
328
+ * overwritten. No-op when the channel has no `enabledBy` actor (e.g.
329
+ * key-based connectors).
330
+ *
331
+ * @param channelId - The channel resource ID whose token is bad
332
+ */
333
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
334
+ abstract markNeedsReauth(channelId: string): Promise<void>;
335
+
267
336
  }
268
337
 
269
338
  /**
package/src/tools/plot.ts CHANGED
@@ -542,18 +542,6 @@ export abstract class Plot extends ITool {
542
542
  */
543
543
  abstract getUserId(): Promise<string>;
544
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
545
  /**
558
546
  * Creates a new schedule for a thread.
559
547
  *
@@ -146,4 +146,48 @@ export abstract class Store extends ITool {
146
146
  * @returns Promise that resolves when all keys are removed
147
147
  */
148
148
  abstract clearAll(): Promise<void>;
149
+
150
+ /**
151
+ * Acquire a self-expiring lock. Returns true if the caller now holds the
152
+ * lock, false if another holder has a non-expired lease.
153
+ *
154
+ * Use this for any operation where you previously hand-rolled a boolean
155
+ * "in progress" flag with manual cleanup on every error path. The lock
156
+ * auto-releases after `ttlMs`, so a crashed/timed-out holder cannot wedge
157
+ * the system permanently — pick a `ttlMs` comfortably longer than the
158
+ * worst-case duration of the protected work.
159
+ *
160
+ * Acquisition is atomic across concurrent callers (the underlying
161
+ * Durable Object serializes operations). Lock keys live in a reserved
162
+ * namespace and never appear in `get` / `list` results.
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * if (!(await this.tools.store.acquireLock(`sync_${id}`, 30 * 60_000))) {
167
+ * return; // another sync is already running
168
+ * }
169
+ * try {
170
+ * await this.runSync(id);
171
+ * } finally {
172
+ * await this.tools.store.releaseLock(`sync_${id}`);
173
+ * }
174
+ * ```
175
+ *
176
+ * @param key Lock identifier (any string).
177
+ * @param ttlMs Lease duration in milliseconds. After this time the lock
178
+ * is considered expired and a new caller can acquire it even if
179
+ * `releaseLock` was never called.
180
+ * @returns Promise resolving to true if acquired, false if held.
181
+ */
182
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
183
+ abstract acquireLock(key: string, ttlMs: number): Promise<boolean>;
184
+
185
+ /**
186
+ * Release a lock acquired via {@link acquireLock}. Safe to call even if
187
+ * the caller never acquired the lock or the lease has already expired.
188
+ *
189
+ * @param key The same key that was passed to `acquireLock`.
190
+ */
191
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
192
+ abstract releaseLock(key: string): Promise<void>;
149
193
  }