@plotday/twister 0.52.0 → 0.54.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 (219) hide show
  1. package/bin/commands/deploy.js +4 -0
  2. package/bin/commands/deploy.js.map +1 -1
  3. package/bin/templates/AGENTS.template.md +6 -10
  4. package/cli/templates/AGENTS.template.md +6 -10
  5. package/dist/connector.d.ts +179 -10
  6. package/dist/connector.d.ts.map +1 -1
  7. package/dist/connector.js +78 -4
  8. package/dist/connector.js.map +1 -1
  9. package/dist/docs/assets/hierarchy.js +1 -1
  10. package/dist/docs/assets/navigation.js +1 -1
  11. package/dist/docs/assets/search.js +1 -1
  12. package/dist/docs/classes/index.Connector.html +74 -26
  13. package/dist/docs/classes/index.FileNotFoundError.html +2 -0
  14. package/dist/docs/classes/index.Files.html +16 -0
  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/tool.ITool.html +1 -1
  19. package/dist/docs/classes/tools_ai.AI.html +7 -5
  20. package/dist/docs/classes/tools_callbacks.Callbacks.html +1 -1
  21. package/dist/docs/classes/tools_integrations.Integrations.html +17 -23
  22. package/dist/docs/classes/tools_network.Network.html +1 -1
  23. package/dist/docs/classes/tools_plot.Plot.html +62 -56
  24. package/dist/docs/classes/tools_store.Store.html +1 -1
  25. package/dist/docs/classes/tools_tasks.Tasks.html +1 -1
  26. package/dist/docs/classes/tools_twists.Twists.html +2 -2
  27. package/dist/docs/classes/twist.Twist.html +3 -3
  28. package/dist/docs/documents/Building_Connectors.html +1 -1
  29. package/dist/docs/enums/plot.ActionType.html +10 -8
  30. package/dist/docs/enums/plot.ActorType.html +4 -4
  31. package/dist/docs/enums/plot.ConferencingProvider.html +6 -6
  32. package/dist/docs/enums/plot.ThemeColor.html +10 -10
  33. package/dist/docs/enums/tag.Tag.html +16 -46
  34. package/dist/docs/enums/tools_ai.AIModel.html +2 -2
  35. package/dist/docs/enums/tools_integrations.AuthProvider.html +13 -13
  36. package/dist/docs/enums/{tools_plot.PriorityAccess.html → tools_plot.FocusAccess.html} +6 -6
  37. package/dist/docs/enums/tools_plot.ThreadAccess.html +1 -1
  38. package/dist/docs/hierarchy.html +1 -1
  39. package/dist/docs/interfaces/tools_ai.AIRequest.html +27 -11
  40. package/dist/docs/interfaces/tools_ai.AIResponse.html +9 -9
  41. package/dist/docs/interfaces/tools_ai.FilePart.html +5 -5
  42. package/dist/docs/interfaces/tools_ai.ImagePart.html +4 -4
  43. package/dist/docs/interfaces/tools_ai.ReasoningPart.html +4 -4
  44. package/dist/docs/interfaces/tools_ai.RedactedReasoningPart.html +3 -3
  45. package/dist/docs/interfaces/tools_ai.TextPart.html +3 -3
  46. package/dist/docs/interfaces/tools_ai.ToolCallPart.html +5 -5
  47. package/dist/docs/interfaces/tools_ai.ToolExecutionOptions.html +4 -4
  48. package/dist/docs/interfaces/tools_ai.ToolResultPart.html +5 -5
  49. package/dist/docs/media/AGENTS.md +22 -14
  50. package/dist/docs/modules/index.html +1 -1
  51. package/dist/docs/modules/plot.html +1 -1
  52. package/dist/docs/modules/tools_integrations.html +1 -1
  53. package/dist/docs/modules/tools_plot.html +1 -1
  54. package/dist/docs/types/index.CreateLinkDraft.html +31 -7
  55. package/dist/docs/types/index.NoteWriteBackResult.html +3 -3
  56. package/dist/docs/types/index.ReactionCapabilities.html +17 -0
  57. package/dist/docs/types/index.ResolvedRecipient.html +24 -0
  58. package/dist/docs/types/index.Schedule.html +1 -1
  59. package/dist/docs/types/plot.Action.html +9 -2
  60. package/dist/docs/types/plot.Actor.html +5 -5
  61. package/dist/docs/types/plot.ActorId.html +1 -1
  62. package/dist/docs/types/plot.Contact.html +4 -4
  63. package/dist/docs/types/plot.ContentType.html +1 -1
  64. package/dist/docs/types/{plot.Priority.html → plot.Focus.html} +14 -11
  65. package/dist/docs/types/plot.FocusUpdate.html +3 -0
  66. package/dist/docs/types/plot.Link.html +16 -16
  67. package/dist/docs/types/plot.LinkUpdate.html +1 -1
  68. package/dist/docs/types/plot.NewActor.html +1 -1
  69. package/dist/docs/types/plot.NewContact.html +1 -1
  70. package/dist/docs/types/plot.NewFocus.html +13 -0
  71. package/dist/docs/types/plot.NewLink.html +6 -6
  72. package/dist/docs/types/plot.NewLinkWithNotes.html +1 -1
  73. package/dist/docs/types/plot.NewNote.html +5 -3
  74. package/dist/docs/types/plot.NewReactions.html +4 -0
  75. package/dist/docs/types/plot.NewTags.html +1 -1
  76. package/dist/docs/types/plot.NewThread.html +6 -4
  77. package/dist/docs/types/plot.NewThreadWithNotes.html +1 -1
  78. package/dist/docs/types/plot.Note.html +2 -2
  79. package/dist/docs/types/plot.NoteUpdate.html +4 -2
  80. package/dist/docs/types/plot.PlanOperation.html +6 -6
  81. package/dist/docs/types/plot.Reaction.html +13 -0
  82. package/dist/docs/types/plot.Reactions.html +3 -0
  83. package/dist/docs/types/plot.Tags.html +1 -1
  84. package/dist/docs/types/plot.Thread.html +1 -1
  85. package/dist/docs/types/plot.ThreadAccessLevel.html +3 -3
  86. package/dist/docs/types/plot.ThreadCommon.html +9 -5
  87. package/dist/docs/types/plot.ThreadFilter.html +2 -2
  88. package/dist/docs/types/plot.ThreadMeta.html +1 -1
  89. package/dist/docs/types/plot.ThreadType.html +4 -4
  90. package/dist/docs/types/plot.ThreadUpdate.html +1 -1
  91. package/dist/docs/types/plot.ThreadWithNotes.html +1 -1
  92. package/dist/docs/types/tools_ai.AIAssistantMessage.html +2 -2
  93. package/dist/docs/types/tools_ai.AICapabilities.html +7 -3
  94. package/dist/docs/types/tools_ai.AIMessage.html +1 -1
  95. package/dist/docs/types/tools_ai.AIOptions.html +2 -2
  96. package/dist/docs/types/tools_ai.AISource.html +1 -1
  97. package/dist/docs/types/tools_ai.AISystemMessage.html +2 -2
  98. package/dist/docs/types/tools_ai.AITool.html +10 -9
  99. package/dist/docs/types/tools_ai.AIToolMessage.html +2 -2
  100. package/dist/docs/types/tools_ai.AIToolSet.html +1 -1
  101. package/dist/docs/types/tools_ai.AIUsage.html +5 -5
  102. package/dist/docs/types/tools_ai.AIUserMessage.html +2 -2
  103. package/dist/docs/types/tools_ai.DataContent.html +1 -1
  104. package/dist/docs/types/tools_ai.ModelPreferences.html +4 -4
  105. package/dist/docs/types/tools_integrations.ArchiveLinkFilter.html +5 -5
  106. package/dist/docs/types/tools_integrations.AuthToken.html +4 -4
  107. package/dist/docs/types/tools_integrations.Authorization.html +4 -4
  108. package/dist/docs/types/tools_integrations.Channel.html +5 -5
  109. package/dist/docs/types/tools_integrations.ComposeConfig.html +35 -0
  110. package/dist/docs/types/tools_integrations.ContactRoleConfig.html +14 -0
  111. package/dist/docs/types/tools_integrations.LinkTypeConfig.html +55 -28
  112. package/dist/docs/types/tools_integrations.SyncContext.html +3 -3
  113. package/dist/docs/types/tools_plot.SearchOptions.html +5 -6
  114. package/dist/docs/types/tools_twists.TwistPermissions.html +1 -1
  115. package/dist/llm-docs/connector.d.ts +1 -1
  116. package/dist/llm-docs/connector.d.ts.map +1 -1
  117. package/dist/llm-docs/connector.js +1 -1
  118. package/dist/llm-docs/connector.js.map +1 -1
  119. package/dist/llm-docs/index.d.ts.map +1 -1
  120. package/dist/llm-docs/index.js +2 -0
  121. package/dist/llm-docs/index.js.map +1 -1
  122. package/dist/llm-docs/plot.d.ts +1 -1
  123. package/dist/llm-docs/plot.d.ts.map +1 -1
  124. package/dist/llm-docs/plot.js +1 -1
  125. package/dist/llm-docs/plot.js.map +1 -1
  126. package/dist/llm-docs/schedule.d.ts +1 -1
  127. package/dist/llm-docs/schedule.d.ts.map +1 -1
  128. package/dist/llm-docs/schedule.js +1 -1
  129. package/dist/llm-docs/schedule.js.map +1 -1
  130. package/dist/llm-docs/tag.d.ts +1 -1
  131. package/dist/llm-docs/tag.d.ts.map +1 -1
  132. package/dist/llm-docs/tag.js +1 -1
  133. package/dist/llm-docs/tag.js.map +1 -1
  134. package/dist/llm-docs/tools/ai.d.ts +1 -1
  135. package/dist/llm-docs/tools/ai.d.ts.map +1 -1
  136. package/dist/llm-docs/tools/ai.js +1 -1
  137. package/dist/llm-docs/tools/ai.js.map +1 -1
  138. package/dist/llm-docs/tools/files.d.ts +9 -0
  139. package/dist/llm-docs/tools/files.d.ts.map +1 -0
  140. package/dist/llm-docs/tools/files.js +8 -0
  141. package/dist/llm-docs/tools/files.js.map +1 -0
  142. package/dist/llm-docs/tools/integrations.d.ts +1 -1
  143. package/dist/llm-docs/tools/integrations.d.ts.map +1 -1
  144. package/dist/llm-docs/tools/integrations.js +1 -1
  145. package/dist/llm-docs/tools/integrations.js.map +1 -1
  146. package/dist/llm-docs/tools/plot.d.ts +1 -1
  147. package/dist/llm-docs/tools/plot.d.ts.map +1 -1
  148. package/dist/llm-docs/tools/plot.js +1 -1
  149. package/dist/llm-docs/tools/plot.js.map +1 -1
  150. package/dist/llm-docs/tools/twists.d.ts +1 -1
  151. package/dist/llm-docs/tools/twists.d.ts.map +1 -1
  152. package/dist/llm-docs/tools/twists.js +1 -1
  153. package/dist/llm-docs/tools/twists.js.map +1 -1
  154. package/dist/llm-docs/twist-guide-template.d.ts +1 -1
  155. package/dist/llm-docs/twist-guide-template.d.ts.map +1 -1
  156. package/dist/llm-docs/twist-guide-template.js +1 -1
  157. package/dist/llm-docs/twist-guide-template.js.map +1 -1
  158. package/dist/llm-docs/twist.d.ts +1 -1
  159. package/dist/llm-docs/twist.d.ts.map +1 -1
  160. package/dist/llm-docs/twist.js +1 -1
  161. package/dist/llm-docs/twist.js.map +1 -1
  162. package/dist/plot.d.ts +146 -85
  163. package/dist/plot.d.ts.map +1 -1
  164. package/dist/plot.js +3 -1
  165. package/dist/plot.js.map +1 -1
  166. package/dist/schedule.d.ts +1 -1
  167. package/dist/tag.d.ts +17 -43
  168. package/dist/tag.d.ts.map +1 -1
  169. package/dist/tag.js +17 -46
  170. package/dist/tag.js.map +1 -1
  171. package/dist/tools/ai.d.ts +46 -10
  172. package/dist/tools/ai.d.ts.map +1 -1
  173. package/dist/tools/ai.js.map +1 -1
  174. package/dist/tools/files.d.ts +33 -0
  175. package/dist/tools/files.d.ts.map +1 -0
  176. package/dist/tools/files.js +22 -0
  177. package/dist/tools/files.js.map +1 -0
  178. package/dist/tools/index.d.ts +1 -0
  179. package/dist/tools/index.d.ts.map +1 -1
  180. package/dist/tools/index.js +1 -0
  181. package/dist/tools/index.js.map +1 -1
  182. package/dist/tools/integrations.d.ts +130 -50
  183. package/dist/tools/integrations.d.ts.map +1 -1
  184. package/dist/tools/integrations.js.map +1 -1
  185. package/dist/tools/plot.d.ts +66 -56
  186. package/dist/tools/plot.d.ts.map +1 -1
  187. package/dist/tools/plot.js +14 -14
  188. package/dist/tools/plot.js.map +1 -1
  189. package/dist/tools/twists.d.ts +2 -2
  190. package/dist/twist-guide.d.ts +1 -1
  191. package/dist/twist-guide.d.ts.map +1 -1
  192. package/dist/twist.d.ts +3 -3
  193. package/dist/twist.js +3 -3
  194. package/package.json +6 -1
  195. package/src/connector.ts +182 -10
  196. package/src/llm-docs/connector.ts +1 -1
  197. package/src/llm-docs/index.ts +2 -0
  198. package/src/llm-docs/plot.ts +1 -1
  199. package/src/llm-docs/schedule.ts +1 -1
  200. package/src/llm-docs/tag.ts +1 -1
  201. package/src/llm-docs/tools/ai.ts +1 -1
  202. package/src/llm-docs/tools/files.ts +8 -0
  203. package/src/llm-docs/tools/integrations.ts +1 -1
  204. package/src/llm-docs/tools/plot.ts +1 -1
  205. package/src/llm-docs/tools/twists.ts +1 -1
  206. package/src/llm-docs/twist-guide-template.ts +1 -1
  207. package/src/llm-docs/twist.ts +1 -1
  208. package/src/plot.ts +156 -75
  209. package/src/schedule.ts +1 -1
  210. package/src/tag.ts +17 -48
  211. package/src/tools/ai.ts +46 -10
  212. package/src/tools/files.ts +37 -0
  213. package/src/tools/index.ts +1 -0
  214. package/src/tools/integrations.ts +131 -61
  215. package/src/tools/plot.ts +69 -59
  216. package/src/tools/twists.ts +2 -2
  217. package/src/twist.ts +3 -3
  218. package/dist/docs/types/plot.NewPriority.html +0 -15
  219. package/dist/docs/types/plot.PriorityUpdate.html +0 -5
package/src/plot.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { NewSchedule, NewScheduleOccurrence, Schedule } from "./schedule";
2
2
  import { type Tag } from "./tag";
3
3
  import { type Callback } from "./tools/callbacks";
4
- import { type AuthProvider } from "./tools/integrations";
5
4
  import { type JSONValue } from "./utils/types";
6
5
  import { Uuid } from "./utils/uuid";
7
6
 
@@ -12,13 +11,13 @@ export { type AuthProvider } from "./tools/integrations";
12
11
 
13
12
  /**
14
13
  * @fileoverview
15
- * Core Plot entity types for working with threads, notes, priorities, and contacts.
14
+ * Core Plot entity types for working with threads, notes, focuses, and contacts.
16
15
  *
17
16
  * ## Type Pattern: Null vs Undefined Semantics
18
17
  *
19
18
  * Plot entity types use a consistent pattern to distinguish between missing, unset, and explicitly cleared values:
20
19
  *
21
- * ### Entity Types (Thread, Priority, Note, Actor)
20
+ * ### Entity Types (Thread, Focus, Note, Actor)
22
21
  * - **Required fields**: No `?`, cannot be `undefined`
23
22
  * - Example: `id: Uuid`, `title: string`
24
23
  * - **Nullable fields**: Use `| null` to allow explicit clearing
@@ -31,10 +30,10 @@ export { type AuthProvider } from "./tools/integrations";
31
30
  * - `null` = field included but not set
32
31
  * - Value = field has a value
33
32
  *
34
- * ### New* Types (NewThread, NewNote, NewPriority)
33
+ * ### New* Types (NewThread, NewNote, NewFocus)
35
34
  * Used for creating or updating entities. Support partial updates by distinguishing omitted vs cleared fields:
36
35
  * - **Required fields**: Must be provided (no `?`)
37
- * - Example: `title: string` in NewPriority
36
+ * - Example: `title: string` in NewFocus
38
37
  * - **Optional fields**: Use `?` to make them optional
39
38
  * - Example: `title?: string`, `author?: NewActor`
40
39
  * - `undefined` (omitted) = don't set/update this field
@@ -77,7 +76,7 @@ export { type AuthProvider } from "./tools/integrations";
77
76
  export type ActorId = string & { readonly __brand: "ActorId" };
78
77
 
79
78
  /**
80
- * Theme colors for priorities.
79
+ * Theme colors for focuses.
81
80
  */
82
81
  export enum ThemeColor {
83
82
  /** Catalyst - Green */
@@ -99,73 +98,67 @@ export enum ThemeColor {
99
98
  }
100
99
 
101
100
  /**
102
- * Represents a priority context within Plot.
101
+ * Represents a focus within Plot.
103
102
  *
104
- * Priorities are similar to projects in other apps. All Activity is in a Priority.
105
- * Priorities can be nested.
103
+ * A focus is similar to a project or area-of-life. All Activity is in a Focus.
104
+ * Focuses are flat — they have no parent and no children. Threads not matched
105
+ * to any focus live in the Inbox.
106
106
  */
107
- export type Priority = {
108
- /** Unique identifier for the priority */
107
+ export type Focus = {
108
+ /** Unique identifier for the focus */
109
109
  id: Uuid;
110
- /** Human-readable title for the priority */
110
+ /** Human-readable title for the focus */
111
111
  title: string;
112
- /** Whether this priority has been archived */
112
+ /** Whether this focus has been archived */
113
113
  archived: boolean;
114
114
  /**
115
- * Optional key for referencing this priority.
116
- * Keys are unique per priority tree (a user's personal priorities or the root of a shared priority).
115
+ * Optional key for referencing this focus.
116
+ * Keys are unique per user.
117
117
  */
118
118
  key: string | null;
119
- /** Optional theme color for the priority (0-7). If not set, inherits from parent or defaults to 7 (Resolution). */
119
+ /** Optional theme color for the focus (0-7). Defaults to 7 (Resolution) when not set. */
120
120
  color: ThemeColor | null;
121
+ /** Optional icon for the focus (a curated icon key). Defaults to the focus icon when not set. */
122
+ icon: string | null;
121
123
  };
122
124
 
123
125
  /**
124
- * Type for creating new priorities.
126
+ * Type for creating new focuses.
125
127
  *
126
128
  * Supports multiple creation patterns:
127
- * - Provide a specific UUID for the priority
128
- * - Provide a key for upsert within the user's priorities
129
+ * - Provide a specific UUID for the focus
130
+ * - Provide a key for upsert within the user's focuses
129
131
  * - Omit both to auto-generate a new UUID
130
- *
131
- * Optionally specify a parent priority by ID or key for hierarchical structures.
132
132
  */
133
- export type NewPriority = Pick<Priority, "title"> &
134
- Partial<Omit<Priority, "id" | "title">> &
133
+ export type NewFocus = Pick<Focus, "title"> &
134
+ Partial<Omit<Focus, "id" | "title">> &
135
135
  (
136
136
  | {
137
137
  /**
138
- * Unique identifier for the priority, generated by Uuid.Generate().
139
- * Specifying an ID allows tools to track and upsert priorities.
138
+ * Unique identifier for the focus, generated by Uuid.Generate().
139
+ * Specifying an ID allows tools to track and upsert focuses.
140
140
  */
141
141
  id: Uuid;
142
142
  }
143
143
  | {
144
144
  /**
145
- * Unique key for the priority within the user's priorities.
145
+ * Unique key for the focus within the user's focuses.
146
146
  * Can be used to upsert without knowing the UUID.
147
- * For example, "@plot" identifies the Plot priority.
147
+ * For example, "@plot" identifies the Plot focus.
148
148
  */
149
149
  key: string;
150
150
  }
151
151
  | {
152
152
  /* Neither id nor key is required. An id will be generated and returned. */
153
153
  }
154
- ) & {
155
- /** Add the new priority as the child of another priority */
156
- parent?: { id: Uuid } | { key: string };
157
- };
154
+ );
158
155
 
159
156
  /**
160
- * Type for updating existing priorities.
161
- * Must provide either id or key to identify the priority to update.
162
- * Set `parent` to move the priority under a new parent (requires PriorityAccess.Full).
157
+ * Type for updating existing focuses.
158
+ * Must provide either id or key to identify the focus to update.
163
159
  */
164
- export type PriorityUpdate = ({ id: Uuid } | { key: string }) &
165
- Partial<Pick<Priority, "title" | "archived">> & {
166
- /** Move the priority under a new parent. Requires PriorityAccess.Full. */
167
- parent?: { id: Uuid } | { key: string };
168
- };
160
+ export type FocusUpdate = ({ id: Uuid } | { key: string }) &
161
+ Partial<Pick<Focus, "title" | "archived">>;
169
162
 
170
163
  /**
171
164
  * Enumeration of supported action types.
@@ -184,6 +177,8 @@ export enum ActionType {
184
177
  conferencing = "conferencing",
185
178
  /** File attachment links stored in R2 */
186
179
  file = "file",
180
+ /** Reference to an attachment hosted by a connector's source system */
181
+ fileRef = "fileRef",
187
182
  /** Thread reference links for navigating to related threads */
188
183
  thread = "thread",
189
184
  /** Structured plan of operations for user approval */
@@ -301,6 +296,22 @@ export type Action =
301
296
  /** Intrinsic height of the image in pixels (only for image files) */
302
297
  imageHeight?: number | null;
303
298
  }
299
+ | {
300
+ /** Reference to an attachment hosted by a connector's source system */
301
+ type: ActionType.fileRef;
302
+ /** Opaque identifier interpreted only by the owning connector */
303
+ ref: string;
304
+ /** Display filename */
305
+ fileName: string;
306
+ /** File size in bytes if known */
307
+ fileSize: number | null;
308
+ /** MIME type */
309
+ mimeType: string;
310
+ /** Intrinsic width of the image in pixels (only for image files) */
311
+ imageWidth?: number | null;
312
+ /** Intrinsic height of the image in pixels (only for image files) */
313
+ imageHeight?: number | null;
314
+ }
304
315
  | {
305
316
  /** Thread reference action for navigating to a related thread */
306
317
  type: ActionType.thread;
@@ -358,9 +369,9 @@ export type ThreadMeta = {
358
369
 
359
370
  /**
360
371
  * Thread sub-type that determines the thread's icon and category.
361
- * Available types depend on whether the priority is shared:
362
- * - Private priorities: "action" (default for tasks), "notes" (default), "idea", "goal", "decision"
363
- * - Shared priorities: all above plus "discussion" (default), "announcement", "ask"
372
+ * Available types depend on whether the focus is shared:
373
+ * - Private focuses: "action" (default for tasks), "notes" (default), "idea", "goal", "decision"
374
+ * - Shared focuses: all above plus "discussion" (default), "announcement", "ask"
364
375
  */
365
376
  export type ThreadType =
366
377
  | "action"
@@ -382,10 +393,39 @@ export type Tags = { [K in Tag]?: ActorId[] };
382
393
  */
383
394
  export type NewTags = { [K in Tag]?: NewActor[] };
384
395
 
396
+ /**
397
+ * A single emoji reaction key. Either:
398
+ * - A Unicode emoji grapheme cluster (e.g. `"👍"`, `"👨‍👩‍👧"`), or
399
+ * - A provider-scoped custom-emoji ref of the form
400
+ * `"<provider>:<workspaceId>/<name>"` (e.g. `"slack:T0123/party_parrot"`).
401
+ *
402
+ * Anything matching a known provider prefix is treated as a custom-emoji
403
+ * reference; everything else is rendered as the Unicode it contains.
404
+ *
405
+ * Reactions are the open-set counterpart to {@link Tag}'s count range
406
+ * (`1000+`). Use reactions for emoji that round-trip with chat platforms;
407
+ * use tags for Plot-managed compute/toggle state (todo, pinned, urgent,
408
+ * ...).
409
+ */
410
+ export type Reaction = string;
411
+
412
+ /**
413
+ * Emoji reactions on an item, keyed by emoji string, with the list of
414
+ * actors who added each reaction.
415
+ */
416
+ export type Reactions = Record<Reaction, ActorId[]>;
417
+
418
+ /**
419
+ * A set of reactions to add to an item, along with the actors adding each
420
+ * reaction. To remove a reaction for a given actor, omit them from the
421
+ * `NewActor[]` list — passing an empty list removes the reaction entirely.
422
+ */
423
+ export type NewReactions = Record<Reaction, NewActor[]>;
424
+
385
425
  /**
386
426
  * Thread access level determining visibility.
387
- * - "public": Visible to all users with priority access
388
- * - "members": Visible to priority members (default for shared priorities)
427
+ * - "public": Visible to all users with focus access
428
+ * - "members": Visible to focus members (default for shared focuses)
389
429
  * - "private": Visible only to creator and contacts listed in accessContacts
390
430
  */
391
431
  export type ThreadAccessLevel = "public" | "members" | "private";
@@ -408,6 +448,12 @@ export type ThreadCommon = {
408
448
  archived: boolean;
409
449
  /** Tags attached to this thread. Maps tag ID to array of actor IDs who added that tag. */
410
450
  tags: Tags;
451
+ /**
452
+ * Emoji reactions on this item. Maps each emoji (Unicode grapheme or
453
+ * `provider:workspace/name` custom-emoji ref) to the list of actor IDs
454
+ * who reacted with it.
455
+ */
456
+ reactions: Reactions;
411
457
  };
412
458
 
413
459
  /**
@@ -417,8 +463,8 @@ export type ThreadCommon = {
417
463
  type ThreadFields = ThreadCommon & {
418
464
  /** The display title/summary of the thread */
419
465
  title: string;
420
- /** The priority context this thread belongs to */
421
- priority: Priority;
466
+ /** The focus context this thread belongs to */
467
+ focus: Focus;
422
468
  /** The thread's sub-type/category. Determines the displayed icon. */
423
469
  type: ThreadType | null;
424
470
  /** Thread access level: "public", "members", or "private" */
@@ -454,7 +500,7 @@ export type NewThreadWithNotes = NewThread & {
454
500
  * ```
455
501
  */
456
502
  export type NewThread = Partial<
457
- Omit<ThreadFields, "priority" | "tags" | "id" | "accessContacts">
503
+ Omit<ThreadFields, "focus" | "tags" | "reactions" | "id" | "accessContacts">
458
504
  > &
459
505
  (
460
506
  | {
@@ -466,14 +512,20 @@ export type NewThread = Partial<
466
512
  }
467
513
  ) &
468
514
  {
469
- /** Explicit priority - disables automatic priority matching. When omitted, the server classifies the thread using the user's priority rules. */
470
- priority?: Pick<Priority, "id">;
515
+ /** Explicit focus - disables automatic focus matching. When omitted, the server classifies the thread using the user's focus rules. */
516
+ focus?: Pick<Focus, "id">;
471
517
  } & {
472
518
  /**
473
519
  * All tags to set on the new thread.
474
520
  */
475
521
  tags?: NewTags;
476
522
 
523
+ /**
524
+ * Emoji reactions to set on the new thread.
525
+ * Each emoji maps to the list of actors who reacted with it.
526
+ */
527
+ reactions?: NewReactions;
528
+
477
529
  /**
478
530
  * The thread's sub-type/category. Sets the thread's icon.
479
531
  * If omitted, defaults to "notes" (private) or "discussion" (shared).
@@ -492,7 +544,7 @@ export type NewThread = Partial<
492
544
  * - undefined/omitted (default): Thread is unread for users, except auto-marked
493
545
  * as read for the author if they are the twist owner (user)
494
546
  * - true: Thread is explicitly unread for ALL users (use sparingly)
495
- * - false: Thread is marked as read for all users in the priority at creation time
547
+ * - false: Thread is marked as read for all users in the focus at creation time
496
548
  */
497
549
  unread?: boolean;
498
550
 
@@ -549,6 +601,12 @@ type ThreadSingleUpdateFields = ThreadBulkUpdateFields & {
549
601
  */
550
602
  tags?: NewTags;
551
603
 
604
+ /**
605
+ * Emoji reactions to change on the thread. Pass an empty `NewActor[]` to
606
+ * remove a reaction entirely; omit an emoji to leave it untouched.
607
+ */
608
+ reactions?: NewReactions;
609
+
552
610
  /**
553
611
  * Add or remove the twist's tags.
554
612
  * Maps tag ID to boolean: true = add tag, false = remove tag.
@@ -574,10 +632,10 @@ type ThreadSingleUpdateFields = ThreadBulkUpdateFields & {
574
632
  preview?: string | null;
575
633
 
576
634
  /**
577
- * Move the thread to a different priority. Requires ThreadAccess.Full.
578
- * The target priority must be owned by the twist's user.
635
+ * Move the thread to a different focus. Requires ThreadAccess.Full.
636
+ * The target focus must be owned by the twist's user.
579
637
  */
580
- priority?: Pick<Priority, "id">;
638
+ focus?: Pick<Focus, "id">;
581
639
  };
582
640
 
583
641
  export type ThreadUpdate =
@@ -635,7 +693,7 @@ export type Note = ThreadCommon & {
635
693
  * When set (even to []), the note is private to the listed contacts plus the creator.
636
694
  */
637
695
  accessContacts: ActorId[] | null;
638
- /** Priority twist IDs (twists/connectors) mentioned for dispatch routing. Does not include user contacts. */
696
+ /** Focus twist IDs (twists/connectors) mentioned for dispatch routing. Does not include user contacts. */
639
697
  mentions: ActorId[];
640
698
  };
641
699
 
@@ -651,7 +709,7 @@ export type Note = ThreadCommon & {
651
709
  export type NewNote = Partial<
652
710
  Omit<
653
711
  Note,
654
- "author" | "thread" | "tags" | "mentions" | "accessContacts" | "id" | "key" | "reNote"
712
+ "author" | "thread" | "tags" | "reactions" | "mentions" | "accessContacts" | "id" | "key" | "reNote"
655
713
  >
656
714
  > &
657
715
  ({ id: Uuid } | { key: string } | {}) & {
@@ -681,6 +739,12 @@ export type NewNote = Partial<
681
739
  */
682
740
  tags?: NewTags;
683
741
 
742
+ /**
743
+ * Emoji reactions to set on the note. Pass an empty `NewActor[]` to
744
+ * remove a reaction entirely; omit an emoji to leave it untouched.
745
+ */
746
+ reactions?: NewReactions;
747
+
684
748
  /**
685
749
  * Contacts who can see this note, or null/undefined to inherit thread visibility.
686
750
  * Accepts resolved ActorId UUIDs or email-based NewContact objects (resolved server-side).
@@ -701,7 +765,7 @@ export type NewNote = Partial<
701
765
  * - undefined/omitted (default): Thread is unread for users, except auto-marked
702
766
  * as read for the author if they are the twist owner (user)
703
767
  * - true: Thread is explicitly unread for ALL users (use sparingly)
704
- * - false: Thread is marked as read for all users in the priority at note creation time
768
+ * - false: Thread is marked as read for all users in the focus at note creation time
705
769
  *
706
770
  * For the default behavior, omit this field entirely.
707
771
  * Use false for initial sync to avoid marking historical items as unread.
@@ -748,6 +812,12 @@ export type NoteUpdate = ({ id: Uuid; key?: string } | { key: string }) &
748
812
  */
749
813
  tags?: NewTags;
750
814
 
815
+ /**
816
+ * Emoji reactions to change on the note. Pass an empty `NewActor[]` to
817
+ * remove a reaction entirely; omit an emoji to leave it untouched.
818
+ */
819
+ reactions?: NewReactions;
820
+
751
821
  /**
752
822
  * Add or remove the twist's tags.
753
823
  * Maps tag ID to boolean: true = add tag, false = remove tag.
@@ -861,8 +931,22 @@ type NewContactBase = {
861
931
  /**
862
932
  * External provider account source. Used for identity resolution
863
933
  * when email is unavailable and for privacy compliance reporting.
934
+ *
935
+ * The runtime scopes the resulting `contact_external_account` row to
936
+ * the dispatching twist instance (i.e. one row per connection per
937
+ * contact), so the same Plot contact can have multiple rows when
938
+ * reachable through multiple connections (e.g. two Slack workspaces,
939
+ * Gmail + Google Chat sharing one Google account).
864
940
  */
865
- source?: { provider: AuthProvider; accountId: string };
941
+ source?: { accountId: string };
942
+ /**
943
+ * Optional connector-defined role for this contact on the thread, matching
944
+ * a `LinkTypeConfig.contactRoles[].id` (e.g. "to" / "cc" / "bcc" for
945
+ * email, "required" / "optional" for calendar). Omitted ⇒ default role.
946
+ * Connectors set this on inbound sync; the runtime persists it under
947
+ * `thread.contact_meta[contact_id].role`.
948
+ */
949
+ role?: string;
866
950
  };
867
951
 
868
952
  /**
@@ -954,7 +1038,7 @@ export type NewLink = Partial<
954
1038
  > & {
955
1039
  /**
956
1040
  * Canonical ID for the item in an external system.
957
- * When set, uniquely identifies the link within a priority tree. This performs
1041
+ * When set, uniquely identifies the link for the user. This performs
958
1042
  * an upsert.
959
1043
  *
960
1044
  * @deprecated Pass `sources: [...]` instead. Both fields can be set during
@@ -988,7 +1072,7 @@ export type NewLink = Partial<
988
1072
  * Whether the thread should be marked as unread for users.
989
1073
  * - undefined/omitted (default): Thread is unread for users, except auto-marked
990
1074
  * as read for the author if they are the twist owner (user)
991
- * - false: Thread is marked as read for all users in the priority at creation time
1075
+ * - false: Thread is marked as read for all users in the focus at creation time
992
1076
  */
993
1077
  unread?: boolean;
994
1078
  /**
@@ -999,11 +1083,11 @@ export type NewLink = Partial<
999
1083
  */
1000
1084
  archived?: boolean;
1001
1085
  /**
1002
- * Explicit priority (disables automatic priority matching).
1086
+ * Explicit focus (disables automatic focus matching).
1003
1087
  * Only used when the link creates a new thread. When omitted, the
1004
- * server classifies the thread using the user's priority rules.
1088
+ * server classifies the thread using the user's focus rules.
1005
1089
  */
1006
- priority?: Pick<Priority, "id">;
1090
+ focus?: Pick<Focus, "id">;
1007
1091
  };
1008
1092
 
1009
1093
  /**
@@ -1051,8 +1135,8 @@ export type PlanOperation =
1051
1135
  /** Current thread title for display */
1052
1136
  threadTitle: string;
1053
1137
  changes: Partial<Pick<ThreadFields, "archived" | "title" | "type">> & {
1054
- /** Move to this priority */
1055
- priority?: { id: Uuid; title: string };
1138
+ /** Move to this focus */
1139
+ focus?: { id: Uuid; title: string };
1056
1140
  };
1057
1141
  }
1058
1142
  | {
@@ -1069,9 +1153,9 @@ export type PlanOperation =
1069
1153
  | {
1070
1154
  type: "createThread";
1071
1155
  title: string;
1072
- priorityId: Uuid;
1073
- /** Priority title for display */
1074
- priorityTitle: string;
1156
+ focusId: Uuid;
1157
+ /** Focus title for display */
1158
+ focusTitle: string;
1075
1159
  }
1076
1160
  | {
1077
1161
  type: "createNote";
@@ -1081,12 +1165,9 @@ export type PlanOperation =
1081
1165
  content: string;
1082
1166
  }
1083
1167
  | {
1084
- type: "updatePriority";
1085
- priorityId: Uuid;
1086
- /** Current priority title for display */
1087
- priorityTitle: string;
1088
- changes: Partial<Pick<Priority, "title" | "archived">> & {
1089
- /** Move under this parent */
1090
- parent?: { id: Uuid; title: string };
1091
- };
1168
+ type: "updateFocus";
1169
+ focusId: Uuid;
1170
+ /** Current focus title for display */
1171
+ focusTitle: string;
1172
+ changes: Partial<Pick<Focus, "title" | "archived">>;
1092
1173
  };
package/src/schedule.ts CHANGED
@@ -14,7 +14,7 @@ export { Uuid } from "./utils/uuid";
14
14
  * Represents a schedule entry for a thread.
15
15
  *
16
16
  * Schedules define when a thread occurs in time. A thread may have zero or more schedules:
17
- * - Shared schedules (userId is null): visible to all members of the thread's priority
17
+ * - Shared schedules (userId is null): visible to all members of the thread's focus
18
18
  * - Per-user schedules (userId set): private ordering/scheduling for a specific user
19
19
  *
20
20
  * For recurring events in the SDK, start/end represent the first occurrence's
package/src/tag.ts CHANGED
@@ -1,54 +1,23 @@
1
1
  /**
2
- * Thread tags. Three types:
3
- * 1. Special tags, which trigger other behaviors
4
- * 2. Toggle tags, which anyone can toggle a shared value on or off
5
- * 3. Count tags, where everyone can add or remove their own
2
+ * Compute tags system state the runtime auto-manages on threads and
3
+ * notes (`todo`, `done`, `twist` activity marker, …).
4
+ *
5
+ * The toggle range (100–999) and count range (1000–1027) have been
6
+ * retired in favour of the open Unicode emoji `Reaction` type — see
7
+ * `@plotday/twister/plot`'s `Reactions` / `NewReactions` and the
8
+ * per-row `note.reactions` / `thread.reactions` fields. Connectors
9
+ * route emoji reactions through `reactions`, not `tags`.
10
+ *
11
+ * `Tag.Twist` is the surviving non-trivial tag: a system marker the
12
+ * runtime adds to a note while a twist is processing it, and clears
13
+ * once the twist returns. It's not user-facing and not a reaction.
6
14
  */
7
15
  export enum Tag {
8
- // Special tags
9
16
  Todo = 1,
10
17
  Done = 3,
11
-
12
- // Toggle tags
13
- Pinned = 100,
14
- Urgent = 101,
15
- Goal = 103,
16
- Decision = 104,
17
- Waiting = 105,
18
- Blocked = 106,
19
- Warning = 107,
20
- Question = 108,
21
- Twist = 109,
22
- Star = 110,
23
- Idea = 111,
24
-
25
- // Count tags
26
- Yes = 1000,
27
- No = 1001,
28
- Volunteer = 1002,
29
- Tada = 1003,
30
- Fire = 1004,
31
- Totally = 1005,
32
- Looking = 1006,
33
- Love = 1007,
34
- Rocket = 1008,
35
- Sparkles = 1009,
36
- Thanks = 1010,
37
- Smile = 1011,
38
- Wave = 1012,
39
- Praise = 1015,
40
- Applause = 1016,
41
- Cool = 1017,
42
- Sad = 1018,
43
- Reply = 1019,
44
- Thinking = 1013,
45
- Remember = 1014,
46
- Agreed = 1020,
47
- Relieved = 1021,
48
- Send = 1022,
49
- Noted = 1023,
50
- Laugh = 1024,
51
- Surprised = 1025,
52
- Confused = 1026,
53
- Dismayed = 1027,
18
+ /** System marker for "a twist is processing this note." Set by the
19
+ * runtime when a twist callback fires, cleared on return. Twists
20
+ * may still write `{ [Tag.Twist]: true | false }` to twistTags to
21
+ * mark/unmark a note explicitly. */
22
+ Twist = 12,
54
23
  }
package/src/tools/ai.ts CHANGED
@@ -69,8 +69,11 @@ export abstract class AI extends ITool {
69
69
  * Returns which AI capabilities are currently available.
70
70
  * Check this before calling prompt() or embed() to gracefully
71
71
  * handle cases where AI is disabled by the user.
72
+ *
73
+ * Built-in tools are accessed as RPC stubs, so from a twist this call
74
+ * resolves asynchronously — always `await` it.
72
75
  */
73
- abstract available(): AICapabilities;
76
+ abstract available(): AICapabilities | Promise<AICapabilities>;
74
77
 
75
78
  /**
76
79
  * Sends a request to an AI model and returns the response using the Vercel AI SDK.
@@ -134,7 +137,7 @@ export abstract class AI extends ITool {
134
137
  * tools: {
135
138
  * getWeather: {
136
139
  * description: "Get weather for a city",
137
- * parameters: Type.Object({
140
+ * inputSchema: Type.Object({
138
141
  * city: Type.String()
139
142
  * }),
140
143
  * execute: async ({ city }) => {
@@ -165,6 +168,12 @@ export type AICapabilities = {
165
168
  prompt: boolean;
166
169
  /** Whether AI embedding generation is available. */
167
170
  embed: boolean;
171
+ /**
172
+ * Whether provider-native web search is available. True for Plot AI and
173
+ * Anthropic/Google BYOK providers; false for OpenAI/custom BYOK providers
174
+ * that don't expose a server-side web search tool through this runtime.
175
+ */
176
+ webSearch: boolean;
168
177
  };
169
178
 
170
179
  /**
@@ -345,6 +354,31 @@ export interface AIRequest<
345
354
  * Controls diversity by limiting to top probability tokens.
346
355
  */
347
356
  topP?: number;
357
+
358
+ /**
359
+ * Enable provider-native web search so the model can retrieve
360
+ * up-to-date information from the web. The search is executed
361
+ * server-side by the provider and any pages used are returned in
362
+ * {@link AIResponse.sources}.
363
+ *
364
+ * Only available on web-search-capable providers (Anthropic and
365
+ * Google). Check {@link AICapabilities.webSearch} via `available()`
366
+ * before relying on it; on unsupported providers the flag is ignored.
367
+ *
368
+ * Pass `true` for defaults, or an object to cap the number of searches.
369
+ */
370
+ webSearch?: boolean | { maxUses?: number };
371
+
372
+ /**
373
+ * Maximum number of sequential generation steps for agentic tool use.
374
+ * When the model calls a tool, its result is fed back and the model is
375
+ * called again, up to `maxSteps` times, until it produces a final answer.
376
+ *
377
+ * Defaults to 1 (single step — tool calls are returned but not looped),
378
+ * preserving prior behavior. Set higher (e.g. 6) to let the model chain
379
+ * tool calls into a final answer.
380
+ */
381
+ maxSteps?: number;
348
382
  }
349
383
 
350
384
  /**
@@ -742,17 +776,19 @@ export interface ToolExecutionOptions {
742
776
  */
743
777
  export type AITool<PARAMETERS extends ToolParameters = any, RESULT = any> = {
744
778
  /**
745
- * The schema of the input that the tool expects. The language model will use this to generate the input.
746
- * It is also used to validate the output of the language model.
747
- * Use descriptions to make the input understandable for the language model.
779
+ * The schema of the input that the tool expects, expressed as a Typebox
780
+ * schema. The language model uses this to generate (and the runtime to
781
+ * validate) the tool input. Use field descriptions to make the input
782
+ * understandable for the model.
783
+ *
784
+ * This is the canonical field read by the runtime. `parameters` is an
785
+ * accepted alias for backwards compatibility.
748
786
  */
749
- parameters: PARAMETERS;
787
+ inputSchema: TSchema;
750
788
  /**
751
- * The schema of the input that the tool expects. The language model will use this to generate the input.
752
- * It is also used to validate the output of the language model.
753
- * Use descriptions to make the input understandable for the language model.
789
+ * @deprecated Alias for {@link inputSchema}. Prefer `inputSchema`.
754
790
  */
755
- inputSchema: TSchema;
791
+ parameters?: PARAMETERS;
756
792
  /**
757
793
  * An optional description of what the tool does.
758
794
  * Will be used by the language model to decide whether to use the tool.