@plotday/twister 0.20.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 (298) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/bin/commands/build.js +108 -0
  4. package/bin/commands/build.js.map +1 -0
  5. package/bin/commands/create.js +230 -0
  6. package/bin/commands/create.js.map +1 -0
  7. package/bin/commands/deploy.js +292 -0
  8. package/bin/commands/deploy.js.map +1 -0
  9. package/bin/commands/generate.js +301 -0
  10. package/bin/commands/generate.js.map +1 -0
  11. package/bin/commands/lint.js +69 -0
  12. package/bin/commands/lint.js.map +1 -0
  13. package/bin/commands/login.js +140 -0
  14. package/bin/commands/login.js.map +1 -0
  15. package/bin/commands/priority-create.js +102 -0
  16. package/bin/commands/priority-create.js.map +1 -0
  17. package/bin/commands/priority-list.js +47 -0
  18. package/bin/commands/priority-list.js.map +1 -0
  19. package/bin/commands/twist-logs.js +187 -0
  20. package/bin/commands/twist-logs.js.map +1 -0
  21. package/bin/index.js +129 -0
  22. package/bin/index.js.map +1 -0
  23. package/bin/package.json +3 -0
  24. package/bin/plot.cjs +3 -0
  25. package/bin/templates/AGENTS.template.md +403 -0
  26. package/bin/templates/CLAUDE.template.md +1 -0
  27. package/bin/templates/README.template.md +189 -0
  28. package/bin/utils/bundle.js +106 -0
  29. package/bin/utils/bundle.js.map +1 -0
  30. package/bin/utils/output.js +133 -0
  31. package/bin/utils/output.js.map +1 -0
  32. package/bin/utils/packageManager.js +65 -0
  33. package/bin/utils/packageManager.js.map +1 -0
  34. package/bin/utils/sse.js +100 -0
  35. package/bin/utils/sse.js.map +1 -0
  36. package/bin/utils/token.js +75 -0
  37. package/bin/utils/token.js.map +1 -0
  38. package/cli/templates/AGENTS.template.md +403 -0
  39. package/cli/templates/CLAUDE.template.md +1 -0
  40. package/cli/templates/README.template.md +189 -0
  41. package/dist/common/calendar.d.ts +144 -0
  42. package/dist/common/calendar.d.ts.map +1 -0
  43. package/dist/common/calendar.js +2 -0
  44. package/dist/common/calendar.js.map +1 -0
  45. package/dist/common/messaging.d.ts +84 -0
  46. package/dist/common/messaging.d.ts.map +1 -0
  47. package/dist/common/messaging.js +2 -0
  48. package/dist/common/messaging.js.map +1 -0
  49. package/dist/creator-docs.d.ts +11 -0
  50. package/dist/creator-docs.d.ts.map +1 -0
  51. package/dist/creator-docs.js +27 -0
  52. package/dist/creator-docs.js.map +1 -0
  53. package/dist/docs/.nojekyll +1 -0
  54. package/dist/docs/assets/favicon.svg +8 -0
  55. package/dist/docs/assets/hierarchy.js +1 -0
  56. package/dist/docs/assets/highlight.css +134 -0
  57. package/dist/docs/assets/icons.js +18 -0
  58. package/dist/docs/assets/icons.svg +1 -0
  59. package/dist/docs/assets/main.js +60 -0
  60. package/dist/docs/assets/navigation.js +1 -0
  61. package/dist/docs/assets/search.js +1 -0
  62. package/dist/docs/assets/style.css +1633 -0
  63. package/dist/docs/classes/tool.ITool.html +4 -0
  64. package/dist/docs/classes/tool.Tool.html +116 -0
  65. package/dist/docs/classes/tools_ai.AI.html +27 -0
  66. package/dist/docs/classes/tools_callbacks.Callbacks.html +45 -0
  67. package/dist/docs/classes/tools_integrations.Integrations.html +26 -0
  68. package/dist/docs/classes/tools_network.Network.html +68 -0
  69. package/dist/docs/classes/tools_plot.Plot.html +82 -0
  70. package/dist/docs/classes/tools_store.Store.html +53 -0
  71. package/dist/docs/classes/tools_tasks.Tasks.html +39 -0
  72. package/dist/docs/classes/tools_twists.Twists.html +59 -0
  73. package/dist/docs/classes/twist.Twist.html +96 -0
  74. package/dist/docs/documents/Advanced.html +91 -0
  75. package/dist/docs/documents/Building_Custom_Tools.html +200 -0
  76. package/dist/docs/documents/Built-in_Tools.html +170 -0
  77. package/dist/docs/documents/CLI_Reference.html +193 -0
  78. package/dist/docs/documents/Core_Concepts.html +163 -0
  79. package/dist/docs/documents/Getting_Started.html +94 -0
  80. package/dist/docs/documents/Runtime_Environment.html +128 -0
  81. package/dist/docs/enums/plot.ActivityLinkType.html +12 -0
  82. package/dist/docs/enums/plot.ActivityType.html +10 -0
  83. package/dist/docs/enums/plot.ActorType.html +10 -0
  84. package/dist/docs/enums/plot.ConferencingProvider.html +14 -0
  85. package/dist/docs/enums/tag.Tag.html +45 -0
  86. package/dist/docs/enums/tools_ai.AIModel.html +31 -0
  87. package/dist/docs/enums/tools_integrations.AuthLevel.html +7 -0
  88. package/dist/docs/enums/tools_integrations.AuthProvider.html +24 -0
  89. package/dist/docs/enums/tools_plot.ActivityAccess.html +8 -0
  90. package/dist/docs/enums/tools_plot.ContactAccess.html +5 -0
  91. package/dist/docs/enums/tools_plot.PriorityAccess.html +8 -0
  92. package/dist/docs/hierarchy.html +1 -0
  93. package/dist/docs/index.html +100 -0
  94. package/dist/docs/interfaces/common_calendar.Calendar.html +13 -0
  95. package/dist/docs/interfaces/common_calendar.CalendarTool.html +49 -0
  96. package/dist/docs/interfaces/common_calendar.SyncOptions.html +8 -0
  97. package/dist/docs/interfaces/tools_ai.AIRequest.html +46 -0
  98. package/dist/docs/interfaces/tools_ai.AIResponse.html +19 -0
  99. package/dist/docs/interfaces/tools_ai.FilePart.html +14 -0
  100. package/dist/docs/interfaces/tools_ai.ImagePart.html +11 -0
  101. package/dist/docs/interfaces/tools_ai.ReasoningPart.html +7 -0
  102. package/dist/docs/interfaces/tools_ai.RedactedReasoningPart.html +5 -0
  103. package/dist/docs/interfaces/tools_ai.TextPart.html +5 -0
  104. package/dist/docs/interfaces/tools_ai.ToolCallPart.html +9 -0
  105. package/dist/docs/interfaces/tools_ai.ToolExecutionOptions.html +9 -0
  106. package/dist/docs/interfaces/tools_ai.ToolResultPart.html +9 -0
  107. package/dist/docs/interfaces/tools_twists.TwistSource.html +13 -0
  108. package/dist/docs/interfaces/utils_types.ToolShed.html +11 -0
  109. package/dist/docs/modules/common_calendar.html +1 -0
  110. package/dist/docs/modules/index.html +1 -0
  111. package/dist/docs/modules/plot.html +1 -0
  112. package/dist/docs/modules/tag.html +1 -0
  113. package/dist/docs/modules/tool.html +1 -0
  114. package/dist/docs/modules/tools_ai.html +1 -0
  115. package/dist/docs/modules/tools_callbacks.html +1 -0
  116. package/dist/docs/modules/tools_integrations.html +1 -0
  117. package/dist/docs/modules/tools_network.html +1 -0
  118. package/dist/docs/modules/tools_plot.html +1 -0
  119. package/dist/docs/modules/tools_store.html +1 -0
  120. package/dist/docs/modules/tools_tasks.html +1 -0
  121. package/dist/docs/modules/tools_twists.html +1 -0
  122. package/dist/docs/modules/twist.html +1 -0
  123. package/dist/docs/modules/utils_types.html +1 -0
  124. package/dist/docs/modules.html +1 -0
  125. package/dist/docs/types/common_calendar.CalendarAuth.html +7 -0
  126. package/dist/docs/types/plot.Activity.html +64 -0
  127. package/dist/docs/types/plot.ActivityLink.html +22 -0
  128. package/dist/docs/types/plot.ActivityMeta.html +11 -0
  129. package/dist/docs/types/plot.ActivityUpdate.html +13 -0
  130. package/dist/docs/types/plot.Actor.html +15 -0
  131. package/dist/docs/types/plot.ActorId.html +4 -0
  132. package/dist/docs/types/plot.NewActivity.html +16 -0
  133. package/dist/docs/types/plot.NewContact.html +13 -0
  134. package/dist/docs/types/plot.NewPriority.html +5 -0
  135. package/dist/docs/types/plot.NoteType.html +1 -0
  136. package/dist/docs/types/plot.PickPriorityConfig.html +22 -0
  137. package/dist/docs/types/plot.Priority.html +8 -0
  138. package/dist/docs/types/tools_ai.AIAssistantMessage.html +4 -0
  139. package/dist/docs/types/tools_ai.AIMessage.html +3 -0
  140. package/dist/docs/types/tools_ai.AISource.html +11 -0
  141. package/dist/docs/types/tools_ai.AISystemMessage.html +7 -0
  142. package/dist/docs/types/tools_ai.AITool.html +19 -0
  143. package/dist/docs/types/tools_ai.AIToolMessage.html +4 -0
  144. package/dist/docs/types/tools_ai.AIToolSet.html +1 -0
  145. package/dist/docs/types/tools_ai.AIUsage.html +10 -0
  146. package/dist/docs/types/tools_ai.AIUserMessage.html +4 -0
  147. package/dist/docs/types/tools_ai.DataContent.html +2 -0
  148. package/dist/docs/types/tools_ai.ModelPreferences.html +24 -0
  149. package/dist/docs/types/tools_callbacks.Callback.html +8 -0
  150. package/dist/docs/types/tools_integrations.AuthToken.html +16 -0
  151. package/dist/docs/types/tools_integrations.Authorization.html +10 -0
  152. package/dist/docs/types/tools_network.WebhookRequest.html +15 -0
  153. package/dist/docs/types/tools_plot.ActivityIntentHandler.html +9 -0
  154. package/dist/docs/types/tools_twists.Log.html +6 -0
  155. package/dist/docs/types/tools_twists.TwistPermissions.html +12 -0
  156. package/dist/docs/types/utils_types.BuiltInTools.html +5 -0
  157. package/dist/docs/types/utils_types.CallbackMethods.html +3 -0
  158. package/dist/docs/types/utils_types.ExtractBuildReturn.html +2 -0
  159. package/dist/docs/types/utils_types.InferOptions.html +2 -0
  160. package/dist/docs/types/utils_types.InferTools.html +3 -0
  161. package/dist/docs/types/utils_types.NoFunctions.html +3 -0
  162. package/dist/docs/types/utils_types.NonFunction.html +2 -0
  163. package/dist/docs/types/utils_types.PromiseValues.html +3 -0
  164. package/dist/docs/types/utils_types.ToolBuilder.html +3 -0
  165. package/dist/index.d.ts +7 -0
  166. package/dist/index.d.ts.map +1 -0
  167. package/dist/index.js +7 -0
  168. package/dist/index.js.map +1 -0
  169. package/dist/llm-docs/common/calendar.d.ts +9 -0
  170. package/dist/llm-docs/common/calendar.d.ts.map +1 -0
  171. package/dist/llm-docs/common/calendar.js +8 -0
  172. package/dist/llm-docs/common/calendar.js.map +1 -0
  173. package/dist/llm-docs/common/messaging.d.ts +9 -0
  174. package/dist/llm-docs/common/messaging.d.ts.map +1 -0
  175. package/dist/llm-docs/common/messaging.js +8 -0
  176. package/dist/llm-docs/common/messaging.js.map +1 -0
  177. package/dist/llm-docs/creator-docs.d.ts +9 -0
  178. package/dist/llm-docs/creator-docs.d.ts.map +1 -0
  179. package/dist/llm-docs/creator-docs.js +8 -0
  180. package/dist/llm-docs/creator-docs.js.map +1 -0
  181. package/dist/llm-docs/index.d.ts +11 -0
  182. package/dist/llm-docs/index.d.ts.map +1 -0
  183. package/dist/llm-docs/index.js +42 -0
  184. package/dist/llm-docs/index.js.map +1 -0
  185. package/dist/llm-docs/plot.d.ts +9 -0
  186. package/dist/llm-docs/plot.d.ts.map +1 -0
  187. package/dist/llm-docs/plot.js +8 -0
  188. package/dist/llm-docs/plot.js.map +1 -0
  189. package/dist/llm-docs/tag.d.ts +9 -0
  190. package/dist/llm-docs/tag.d.ts.map +1 -0
  191. package/dist/llm-docs/tag.js +8 -0
  192. package/dist/llm-docs/tag.js.map +1 -0
  193. package/dist/llm-docs/tool.d.ts +9 -0
  194. package/dist/llm-docs/tool.d.ts.map +1 -0
  195. package/dist/llm-docs/tool.js +8 -0
  196. package/dist/llm-docs/tool.js.map +1 -0
  197. package/dist/llm-docs/tools/ai.d.ts +9 -0
  198. package/dist/llm-docs/tools/ai.d.ts.map +1 -0
  199. package/dist/llm-docs/tools/ai.js +8 -0
  200. package/dist/llm-docs/tools/ai.js.map +1 -0
  201. package/dist/llm-docs/tools/callbacks.d.ts +9 -0
  202. package/dist/llm-docs/tools/callbacks.d.ts.map +1 -0
  203. package/dist/llm-docs/tools/callbacks.js +8 -0
  204. package/dist/llm-docs/tools/callbacks.js.map +1 -0
  205. package/dist/llm-docs/tools/integrations.d.ts +9 -0
  206. package/dist/llm-docs/tools/integrations.d.ts.map +1 -0
  207. package/dist/llm-docs/tools/integrations.js +8 -0
  208. package/dist/llm-docs/tools/integrations.js.map +1 -0
  209. package/dist/llm-docs/tools/network.d.ts +9 -0
  210. package/dist/llm-docs/tools/network.d.ts.map +1 -0
  211. package/dist/llm-docs/tools/network.js +8 -0
  212. package/dist/llm-docs/tools/network.js.map +1 -0
  213. package/dist/llm-docs/tools/plot.d.ts +9 -0
  214. package/dist/llm-docs/tools/plot.d.ts.map +1 -0
  215. package/dist/llm-docs/tools/plot.js +8 -0
  216. package/dist/llm-docs/tools/plot.js.map +1 -0
  217. package/dist/llm-docs/tools/store.d.ts +9 -0
  218. package/dist/llm-docs/tools/store.d.ts.map +1 -0
  219. package/dist/llm-docs/tools/store.js +8 -0
  220. package/dist/llm-docs/tools/store.js.map +1 -0
  221. package/dist/llm-docs/tools/tasks.d.ts +9 -0
  222. package/dist/llm-docs/tools/tasks.d.ts.map +1 -0
  223. package/dist/llm-docs/tools/tasks.js +8 -0
  224. package/dist/llm-docs/tools/tasks.js.map +1 -0
  225. package/dist/llm-docs/tools/twists.d.ts +9 -0
  226. package/dist/llm-docs/tools/twists.d.ts.map +1 -0
  227. package/dist/llm-docs/tools/twists.js +8 -0
  228. package/dist/llm-docs/tools/twists.js.map +1 -0
  229. package/dist/llm-docs/twist-guide-template.d.ts +9 -0
  230. package/dist/llm-docs/twist-guide-template.d.ts.map +1 -0
  231. package/dist/llm-docs/twist-guide-template.js +8 -0
  232. package/dist/llm-docs/twist-guide-template.js.map +1 -0
  233. package/dist/llm-docs/twist.d.ts +9 -0
  234. package/dist/llm-docs/twist.d.ts.map +1 -0
  235. package/dist/llm-docs/twist.js +8 -0
  236. package/dist/llm-docs/twist.js.map +1 -0
  237. package/dist/plot.d.ts +463 -0
  238. package/dist/plot.d.ts.map +1 -0
  239. package/dist/plot.js +68 -0
  240. package/dist/plot.js.map +1 -0
  241. package/dist/tag.d.ts +47 -0
  242. package/dist/tag.d.ts.map +1 -0
  243. package/dist/tag.js +51 -0
  244. package/dist/tag.js.map +1 -0
  245. package/dist/tool.d.ts +242 -0
  246. package/dist/tool.d.ts.map +1 -0
  247. package/dist/tool.js +283 -0
  248. package/dist/tool.js.map +1 -0
  249. package/dist/tools/ai.d.ts +697 -0
  250. package/dist/tools/ai.d.ts.map +1 -0
  251. package/dist/tools/ai.js +104 -0
  252. package/dist/tools/ai.js.map +1 -0
  253. package/dist/tools/callbacks.d.ts +96 -0
  254. package/dist/tools/callbacks.d.ts.map +1 -0
  255. package/dist/tools/callbacks.js +40 -0
  256. package/dist/tools/callbacks.js.map +1 -0
  257. package/dist/tools/index.d.ts +9 -0
  258. package/dist/tools/index.d.ts.map +1 -0
  259. package/dist/tools/index.js +9 -0
  260. package/dist/tools/index.js.map +1 -0
  261. package/dist/tools/integrations.d.ts +142 -0
  262. package/dist/tools/integrations.d.ts.map +1 -0
  263. package/dist/tools/integrations.js +79 -0
  264. package/dist/tools/integrations.js.map +1 -0
  265. package/dist/tools/network.d.ts +188 -0
  266. package/dist/tools/network.d.ts.map +1 -0
  267. package/dist/tools/network.js +87 -0
  268. package/dist/tools/network.js.map +1 -0
  269. package/dist/tools/plot.d.ts +252 -0
  270. package/dist/tools/plot.d.ts.map +1 -0
  271. package/dist/tools/plot.js +72 -0
  272. package/dist/tools/plot.js.map +1 -0
  273. package/dist/tools/store.d.ts +90 -0
  274. package/dist/tools/store.d.ts.map +1 -0
  275. package/dist/tools/store.js +48 -0
  276. package/dist/tools/store.js.map +1 -0
  277. package/dist/tools/tasks.d.ts +93 -0
  278. package/dist/tools/tasks.d.ts.map +1 -0
  279. package/dist/tools/tasks.js +58 -0
  280. package/dist/tools/tasks.js.map +1 -0
  281. package/dist/tools/twists.d.ts +213 -0
  282. package/dist/tools/twists.d.ts.map +1 -0
  283. package/dist/tools/twists.js +26 -0
  284. package/dist/tools/twists.js.map +1 -0
  285. package/dist/twist-guide.d.ts +2 -0
  286. package/dist/twist-guide.d.ts.map +1 -0
  287. package/dist/twist-guide.js +9 -0
  288. package/dist/twist-guide.js.map +1 -0
  289. package/dist/twist.d.ts +204 -0
  290. package/dist/twist.d.ts.map +1 -0
  291. package/dist/twist.js +216 -0
  292. package/dist/twist.js.map +1 -0
  293. package/dist/utils/types.d.ts +91 -0
  294. package/dist/utils/types.d.ts.map +1 -0
  295. package/dist/utils/types.js +2 -0
  296. package/dist/utils/types.js.map +1 -0
  297. package/package.json +206 -0
  298. package/tsconfig.base.json +28 -0
@@ -0,0 +1,163 @@
1
+ <!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Core Concepts | Creating Plot Twists</title><link rel="icon" href="../assets/favicon.svg" type="image/svg+xml"/><meta name="description" content="Documentation for Creating Plot Twists"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="/" class="title">Creating Plot Twists</a><div id="tsd-toolbar-links"><a href="https://plot.day">Plot</a><a href="https://github.com/plotday/plot">GitHub</a><a href="https://www.npmjs.com/package/@plotday/twister">NPM</a></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">Core Concepts</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="core-concepts" class="tsd-anchor-link">Core Concepts<a href="#core-concepts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>Understanding these core concepts will help you build effective Plot Twists.</p>
2
+ <h2 id="table-of-contents" class="tsd-anchor-link">Table of Contents<a href="#table-of-contents" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
3
+ <li><a href="#twists">Twists</a></li>
4
+ <li><a href="#twist-tools">Twist Tools</a></li>
5
+ <li><a href="#priorities">Priorities</a></li>
6
+ <li><a href="#activities">Activities</a></li>
7
+ <li><a href="#lifecycle-methods">Lifecycle Methods</a></li>
8
+ <li><a href="#best-practices">Best Practices</a></li>
9
+ </ul>
10
+ <hr>
11
+ <h2 id="twists" class="tsd-anchor-link">Twists<a href="#twists" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Twists are smart automations that connect, organize, and prioritize your work. They implement opinionated workflows and integrations.</p>
12
+ <h3 id="what-is-a-twist" class="tsd-anchor-link">What is a Twist?<a href="#what-is-a-twist" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>A twist is a class that:</p>
13
+ <ul>
14
+ <li>Extends the <code>Twist&lt;T&gt;</code> base class</li>
15
+ <li>Declares tool dependencies in the <code>build()</code> method</li>
16
+ <li>Responds to lifecycle events (<code>activate</code>, <code>deactivate</code>, <code>upgrade</code>)</li>
17
+ <li>Can process activities and create new ones</li>
18
+ </ul>
19
+ <h3 id="twist-anatomy" class="tsd-anchor-link">Twist Anatomy<a href="#twist-anatomy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">Twist</span><span class="hl-1">, </span><span class="hl-0">type</span><span class="hl-1"> </span><span class="hl-2">Priority</span><span class="hl-1">, </span><span class="hl-0">type</span><span class="hl-1"> </span><span class="hl-2">ToolBuilder</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&quot;@plotday/twister&quot;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">Plot</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&quot;@plotday/twister/tools/plot&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-0">default</span><span class="hl-1"> </span><span class="hl-4">class</span><span class="hl-1"> </span><span class="hl-5">MyTwist</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-5">Twist</span><span class="hl-1">&lt;</span><span class="hl-5">MyTwist</span><span class="hl-1">&gt; {</span><br/><span class="hl-1"> </span><span class="hl-7">// 1. Declare dependencies</span><br/><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">build</span><span class="hl-1">: </span><span class="hl-5">ToolBuilder</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">plot:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Plot</span><span class="hl-1">),</span><br/><span class="hl-1"> };</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// 2. Initialize on activation</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">activate</span><span class="hl-1">(</span><span class="hl-2">priority</span><span class="hl-1">: </span><span class="hl-5">Pick</span><span class="hl-1">&lt;</span><span class="hl-5">Priority</span><span class="hl-1">, </span><span class="hl-3">&quot;id&quot;</span><span class="hl-1">&gt;) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Setup code - runs once when twist is added to a priority</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// 3. Handle lifecycle events</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">upgrade</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-7">// Runs when a new version is deployed</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">deactivate</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-7">// Cleanup - runs when twist is removed</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
20
+ </code><button type="button">Copy</button></pre>
21
+
22
+ <h3 id="when-to-use-twists" class="tsd-anchor-link">When to Use Twists<a href="#when-to-use-twists" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Use twists for:</p>
23
+ <ul>
24
+ <li><strong>Integrations</strong> - Connecting external services (Google Calendar, GitHub, Slack)</li>
25
+ <li><strong>Automations</strong> - Automatic task creation, reminders, status updates</li>
26
+ <li><strong>Data Processing</strong> - Analyzing and organizing activities</li>
27
+ <li><strong>Notifications</strong> - Sending alerts based on conditions</li>
28
+ </ul>
29
+ <hr>
30
+ <h2 id="twist-tools" class="tsd-anchor-link">Twist Tools<a href="#twist-tools" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Twist tools provide capabilities to twists. They are usually unopinionated and do nothing on their own. Tools encapsulate reusable capabilities and can be composed together.</p>
31
+ <h3 id="types-of-tools" class="tsd-anchor-link">Types of Tools<a href="#types-of-tools" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><h4 id="1-built-in-tools" class="tsd-anchor-link">1. Built-in Tools<a href="#1-built-in-tools" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Core Plot functionality provided by the Twist Creator:</p>
32
+ <ul>
33
+ <li><strong>Plot</strong> - Create and manage activities and priorities</li>
34
+ <li><strong>Store</strong> - Persistent key-value storage</li>
35
+ <li><strong>Integrations</strong> - OAuth authentication</li>
36
+ <li><strong>Tasks</strong> - Background task execution</li>
37
+ <li><strong>Network</strong> - HTTP access and webhooks</li>
38
+ <li><strong>Callbacks</strong> - Persistent function references</li>
39
+ <li><strong>AI</strong> - Language model integration</li>
40
+ </ul>
41
+ <p>See the <a href="Built-in_Tools.html">Built-in Tools Guide</a> for complete documentation.</p>
42
+ <h4 id="2-custom-tools" class="tsd-anchor-link">2. Custom Tools<a href="#2-custom-tools" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Tools you create or install from npm packages:</p>
43
+ <ul>
44
+ <li><strong>External Service Integrations</strong> - Google Calendar, Slack, GitHub</li>
45
+ <li><strong>Data Processors</strong> - Text analysis, image processing</li>
46
+ <li><strong>Utilities</strong> - Date formatting, validation</li>
47
+ </ul>
48
+ <p>See <a href="Building_Custom_Tools.html">Building Custom Tools</a> to create your own.</p>
49
+ <h3 id="declaring-tool-dependencies" class="tsd-anchor-link">Declaring Tool Dependencies<a href="#declaring-tool-dependencies" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Use the <code>build()</code> method to declare which tools your twist needs:</p>
50
+ <pre><code class="typescript"><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">build</span><span class="hl-1">: </span><span class="hl-2">ToolBuilder</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">plot:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Plot</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-2">store:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Store</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-2">calendar:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">GoogleCalendar</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-7">// Tool-specific options</span><br/><span class="hl-1"> </span><span class="hl-2">defaultCalendar:</span><span class="hl-1"> </span><span class="hl-3">&quot;primary&quot;</span><br/><span class="hl-1"> }),</span><br/><span class="hl-1"> };</span><br/><span class="hl-1">}</span>
51
+ </code><button type="button">Copy</button></pre>
52
+
53
+ <h3 id="accessing-tools" class="tsd-anchor-link">Accessing Tools<a href="#accessing-tools" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Access your tools via <code>this.tools</code>:</p>
54
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">activate</span><span class="hl-1">(</span><span class="hl-2">priority</span><span class="hl-1">: </span><span class="hl-2">Pick</span><span class="hl-1">&lt;</span><span class="hl-2">Priority</span><span class="hl-1">, </span><span class="hl-3">&quot;id&quot;</span><span class="hl-1">&gt;) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Tools are fully typed</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Note</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Hello from my twist&quot;</span><br/><span class="hl-1"> });</span><br/><span class="hl-1">}</span>
55
+ </code><button type="button">Copy</button></pre>
56
+
57
+ <h3 id="direct-access-methods" class="tsd-anchor-link">Direct Access Methods<a href="#direct-access-methods" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Some tool methods are available directly on the Twist class for convenience:</p>
58
+ <pre><code class="typescript"><span class="hl-7">// Store</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">(</span><span class="hl-3">&quot;key&quot;</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;key&quot;</span><span class="hl-1">, </span><span class="hl-2">value</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;key&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-7">// Tasks</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">cancelTask</span><span class="hl-1">(</span><span class="hl-2">token</span><span class="hl-1">);</span><br/><br/><span class="hl-7">// Callbacks</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;methodName&quot;</span><span class="hl-1">, ...</span><span class="hl-2">args</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">run</span><span class="hl-1">(</span><span class="hl-2">callbackToken</span><span class="hl-1">);</span>
59
+ </code><button type="button">Copy</button></pre>
60
+
61
+ <hr>
62
+ <h2 id="priorities" class="tsd-anchor-link">Priorities<a href="#priorities" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Priorities are contexts that organize activities. Think of them like projects or focus areas.</p>
63
+ <h3 id="priority-hierarchy" class="tsd-anchor-link">Priority Hierarchy<a href="#priority-hierarchy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Priorities can be nested to create hierarchies:</p>
64
+ <pre><code><span class="hl-2">Work</span><br/><span class="hl-1">├── </span><span class="hl-2">Project</span><span class="hl-1"> </span><span class="hl-8">A</span><br/><span class="hl-1">│ ├── </span><span class="hl-2">Backend</span><br/><span class="hl-1">│ └── </span><span class="hl-2">Frontend</span><br/><span class="hl-1">└── </span><span class="hl-2">Project</span><span class="hl-1"> </span><span class="hl-8">B</span>
65
+ </code><button>Copy</button></pre>
66
+
67
+ <h3 id="creating-priorities" class="tsd-anchor-link">Creating Priorities<a href="#creating-priorities" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-7">// Top-level priority</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">work</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createPriority</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Work&quot;</span><span class="hl-1">,</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-7">// Nested priority</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">projectA</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createPriority</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Project A&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">parentId:</span><span class="hl-1"> </span><span class="hl-2">work</span><span class="hl-1">.</span><span class="hl-2">id</span><span class="hl-1">,</span><br/><span class="hl-1">});</span>
68
+ </code><button type="button">Copy</button></pre>
69
+
70
+ <h3 id="twist-activation" class="tsd-anchor-link">Twist Activation<a href="#twist-activation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Twists are activated within a specific priority. When activated, the twist has access to that priority and all its children.</p>
71
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">activate</span><span class="hl-1">(</span><span class="hl-2">priority</span><span class="hl-1">: </span><span class="hl-2">Pick</span><span class="hl-1">&lt;</span><span class="hl-2">Priority</span><span class="hl-1">, </span><span class="hl-3">&quot;id&quot;</span><span class="hl-1">&gt;) {</span><br/><span class="hl-1"> </span><span class="hl-7">// This twist is now active for this priority</span><br/><span class="hl-1"> </span><span class="hl-7">// It can create activities, set up webhooks, etc.</span><br/><span class="hl-1">}</span>
72
+ </code><button type="button">Copy</button></pre>
73
+
74
+ <hr>
75
+ <h2 id="activities" class="tsd-anchor-link">Activities<a href="#activities" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Activities are the core data type in Plot, representing tasks, events, and notes.</p>
76
+ <h3 id="activity-types" class="tsd-anchor-link">Activity Types<a href="#activity-types" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><ul>
77
+ <li><strong>Note</strong> - Information without actionable requirements</li>
78
+ <li><strong>Task</strong> - Actionable items that can be completed</li>
79
+ <li><strong>Event</strong> - Scheduled occurrences with start/end times</li>
80
+ </ul>
81
+ <pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">ActivityType</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&quot;@plotday/twister&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-7">// Note</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Note</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Meeting notes from sync&quot;</span><span class="hl-1">,</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-7">// Task</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Task</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Review pull request&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">doneAt:</span><span class="hl-1"> </span><span class="hl-4">null</span><span class="hl-1">, </span><span class="hl-7">// null = not done</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-7">// Event</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Event</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Team standup&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">start:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">(</span><span class="hl-3">&quot;2025-02-01T10:00:00Z&quot;</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-2">end:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">(</span><span class="hl-3">&quot;2025-02-01T10:30:00Z&quot;</span><span class="hl-1">),</span><br/><span class="hl-1">});</span>
82
+ </code><button type="button">Copy</button></pre>
83
+
84
+ <h3 id="activity-properties" class="tsd-anchor-link">Activity Properties<a href="#activity-properties" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-4">type</span><span class="hl-1"> </span><span class="hl-5">Activity</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-2">id</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1">; </span><span class="hl-7">// Unique identifier</span><br/><span class="hl-1"> </span><span class="hl-2">type</span><span class="hl-1">: </span><span class="hl-5">ActivityType</span><span class="hl-1">; </span><span class="hl-7">// Note, Task, or Event</span><br/><span class="hl-1"> </span><span class="hl-2">title</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">; </span><span class="hl-7">// Display title</span><br/><span class="hl-1"> </span><span class="hl-2">note</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">; </span><span class="hl-7">// Additional details</span><br/><span class="hl-1"> </span><span class="hl-2">start</span><span class="hl-1">: </span><span class="hl-5">Date</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">; </span><span class="hl-7">// Event start time</span><br/><span class="hl-1"> </span><span class="hl-2">end</span><span class="hl-1">: </span><span class="hl-5">Date</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">; </span><span class="hl-7">// Event end time</span><br/><span class="hl-1"> </span><span class="hl-2">doneAt</span><span class="hl-1">: </span><span class="hl-5">Date</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">; </span><span class="hl-7">// Task completion time</span><br/><span class="hl-1"> </span><span class="hl-2">links</span><span class="hl-1">: </span><span class="hl-5">ActivityLink</span><span class="hl-1">[]; </span><span class="hl-7">// Action links</span><br/><span class="hl-1"> </span><span class="hl-2">tags</span><span class="hl-1">: </span><span class="hl-5">Record</span><span class="hl-1">&lt;</span><span class="hl-5">Tag</span><span class="hl-1">, </span><span class="hl-5">ActorId</span><span class="hl-1">[]&gt;; </span><span class="hl-7">// Tag assignments</span><br/><span class="hl-1"> </span><span class="hl-7">// ... and more</span><br/><span class="hl-1">};</span>
85
+ </code><button type="button">Copy</button></pre>
86
+
87
+ <h3 id="activity-links" class="tsd-anchor-link">Activity Links<a href="#activity-links" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Links enable user interaction with activities:</p>
88
+ <pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">ActivityLinkType</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&quot;@plotday/twister&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Task</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Fix bug #123&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">links:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityLinkType</span><span class="hl-1">.</span><span class="hl-2">external</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;View Issue&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">url:</span><span class="hl-1"> </span><span class="hl-3">&quot;https://github.com/org/repo/issues/123&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityLinkType</span><span class="hl-1">.</span><span class="hl-2">callback</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Mark as Fixed&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">callback:</span><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;markAsFixed&quot;</span><span class="hl-1">, </span><span class="hl-3">&quot;123&quot;</span><span class="hl-1">),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> ],</span><br/><span class="hl-1">});</span>
89
+ </code><button type="button">Copy</button></pre>
90
+
91
+ <p><strong>Link Types:</strong></p>
92
+ <ul>
93
+ <li><strong>external</strong> - Opens URL in browser</li>
94
+ <li><strong>auth</strong> - Initiates OAuth flow</li>
95
+ <li><strong>callback</strong> - Triggers twist method when clicked</li>
96
+ </ul>
97
+ <hr>
98
+ <h2 id="lifecycle-methods" class="tsd-anchor-link">Lifecycle Methods<a href="#lifecycle-methods" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Twists have several lifecycle methods that are called at specific times.</p>
99
+ <h3 id="activatepriority" class="tsd-anchor-link">activate(priority)<a href="#activatepriority" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Called when the twist is first activated for a priority.</p>
100
+ <p><strong>Use for:</strong></p>
101
+ <ul>
102
+ <li>Creating initial activities</li>
103
+ <li>Setting up webhooks</li>
104
+ <li>Initializing state</li>
105
+ <li>Requesting authentication</li>
106
+ </ul>
107
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">activate</span><span class="hl-1">(</span><span class="hl-2">priority</span><span class="hl-1">: </span><span class="hl-2">Pick</span><span class="hl-1">&lt;</span><span class="hl-2">Priority</span><span class="hl-1">, </span><span class="hl-3">&quot;id&quot;</span><span class="hl-1">&gt;) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Create welcome message</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Note</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Calendar sync is now active&quot;</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Set up webhook</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">webhookUrl</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">network</span><span class="hl-1">.</span><span class="hl-6">createWebhook</span><span class="hl-1">(</span><span class="hl-3">&quot;onUpdate&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;webhook_url&quot;</span><span class="hl-1">, </span><span class="hl-2">webhookUrl</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
108
+ </code><button type="button">Copy</button></pre>
109
+
110
+ <h3 id="upgrade" class="tsd-anchor-link">upgrade()<a href="#upgrade" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Called when a new version of your twist is deployed to an existing priority.</p>
111
+ <p><strong>Use for:</strong></p>
112
+ <ul>
113
+ <li>Migrating data structures</li>
114
+ <li>Updating webhook configurations</li>
115
+ <li>Adding new features to existing installations</li>
116
+ </ul>
117
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">upgrade</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-7">// Check version and migrate</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">version</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">string</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;version&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">version</span><span class="hl-1"> || </span><span class="hl-2">version</span><span class="hl-1"> &lt; </span><span class="hl-3">&quot;2.0.0&quot;</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Migrate old data format</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">oldData</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">(</span><span class="hl-3">&quot;old_key&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;new_key&quot;</span><span class="hl-1">, </span><span class="hl-6">transformData</span><span class="hl-1">(</span><span class="hl-2">oldData</span><span class="hl-1">));</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;old_key&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;version&quot;</span><span class="hl-1">, </span><span class="hl-3">&quot;2.0.0&quot;</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
118
+ </code><button type="button">Copy</button></pre>
119
+
120
+ <h3 id="deactivate" class="tsd-anchor-link">deactivate()<a href="#deactivate" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Called when the twist is removed from a priority.</p>
121
+ <p><strong>Use for:</strong></p>
122
+ <ul>
123
+ <li>Removing webhooks</li>
124
+ <li>Cleanup of external resources</li>
125
+ <li>Final data operations</li>
126
+ </ul>
127
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">deactivate</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-7">// Clean up webhook</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">webhookUrl</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">string</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;webhook_url&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">webhookUrl</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">network</span><span class="hl-1">.</span><span class="hl-6">deleteWebhook</span><span class="hl-1">(</span><span class="hl-2">webhookUrl</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Clean up stored data</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clearAll</span><span class="hl-1">();</span><br/><span class="hl-1">}</span>
128
+ </code><button type="button">Copy</button></pre>
129
+
130
+ <hr>
131
+ <h2 id="best-practices" class="tsd-anchor-link">Best Practices<a href="#best-practices" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="1-state-management" class="tsd-anchor-link">1. State Management<a href="#1-state-management" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Use the Store tool for persistent state, not instance variables:</p>
132
+ <pre><code class="typescript"><span class="hl-7">// ❌ WRONG - Instance variables don&#39;t persist</span><br/><span class="hl-4">class</span><span class="hl-1"> </span><span class="hl-5">MyTwist</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-5">Twist</span><span class="hl-1">&lt;</span><span class="hl-5">MyTwist</span><span class="hl-1">&gt; {</span><br/><span class="hl-1"> </span><span class="hl-4">private</span><span class="hl-1"> </span><span class="hl-2">syncToken</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1">; </span><span class="hl-7">// This will be lost!</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT - Use Store</span><br/><span class="hl-4">class</span><span class="hl-1"> </span><span class="hl-5">MyTwist</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-5">Twist</span><span class="hl-1">&lt;</span><span class="hl-5">MyTwist</span><span class="hl-1">&gt; {</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">getSyncToken</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">string</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_token&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">setSyncToken</span><span class="hl-1">(</span><span class="hl-2">token</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_token&quot;</span><span class="hl-1">, </span><span class="hl-2">token</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
133
+ </code><button type="button">Copy</button></pre>
134
+
135
+ <h3 id="2-error-handling" class="tsd-anchor-link">2. Error Handling<a href="#2-error-handling" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Always handle errors gracefully:</p>
136
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">activate</span><span class="hl-1">(</span><span class="hl-2">priority</span><span class="hl-1">: </span><span class="hl-2">Pick</span><span class="hl-1">&lt;</span><span class="hl-2">Priority</span><span class="hl-1">, </span><span class="hl-3">&quot;id&quot;</span><span class="hl-1">&gt;) {</span><br/><span class="hl-1"> </span><span class="hl-0">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Note</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Twist activated&quot;</span><br/><span class="hl-1"> });</span><br/><span class="hl-1"> } </span><span class="hl-0">catch</span><span class="hl-1"> (</span><span class="hl-2">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">error</span><span class="hl-1">(</span><span class="hl-3">&quot;Failed to create activity:&quot;</span><span class="hl-1">, </span><span class="hl-2">error</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Twist activation continues even if this fails</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
137
+ </code><button type="button">Copy</button></pre>
138
+
139
+ <h3 id="3-batch-long-operations" class="tsd-anchor-link">3. Batch Long Operations<a href="#3-batch-long-operations" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Break long-running operations into batches:</p>
140
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncBatch&quot;</span><span class="hl-1">, { </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-12">1</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncBatch</span><span class="hl-1">(</span><span class="hl-2">args</span><span class="hl-1">: </span><span class="hl-2">any</span><span class="hl-1">, </span><span class="hl-2">context</span><span class="hl-1">: { </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-2">number</span><span class="hl-1"> }) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Process one page</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">hasMore</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">processPage</span><span class="hl-1">(</span><span class="hl-2">context</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Queue next batch</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncBatch&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-2">context</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1"> + </span><span class="hl-12">1</span><br/><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
141
+ </code><button type="button">Copy</button></pre>
142
+
143
+ <p>See <a href="Runtime_Environment.html">Runtime Environment</a> for more details.</p>
144
+ <h3 id="4-type-safety" class="tsd-anchor-link">4. Type Safety<a href="#4-type-safety" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Leverage TypeScript for type safety:</p>
145
+ <pre><code class="typescript"><span class="hl-7">// Define interfaces for stored data</span><br/><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-5">SyncState</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">lastSync</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">token</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">status</span><span class="hl-1">: </span><span class="hl-3">&quot;active&quot;</span><span class="hl-1"> | </span><span class="hl-3">&quot;paused&quot;</span><span class="hl-1">;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">getSyncState</span><span class="hl-1">(): </span><span class="hl-5">Promise</span><span class="hl-1">&lt;</span><span class="hl-2">SyncState</span><span class="hl-1"> | </span><span class="hl-4">null</span><span class="hl-1">&gt; {</span><br/><span class="hl-1"> return await this.get&lt;SyncState&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-2">);</span><br/><span class="hl-2">}</span>
146
+ </code><button type="button">Copy</button></pre>
147
+
148
+ <h3 id="5-tool-composition" class="tsd-anchor-link">5. Tool Composition<a href="#5-tool-composition" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Build complex functionality by composing tools:</p>
149
+ <pre><code class="typescript"><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">build</span><span class="hl-1">: </span><span class="hl-2">ToolBuilder</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">plot:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Plot</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-2">network:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Network</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">urls:</span><span class="hl-1"> [</span><span class="hl-3">&quot;https://api.service.com/*&quot;</span><span class="hl-1">]</span><br/><span class="hl-1"> }),</span><br/><span class="hl-1"> </span><span class="hl-2">auth:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Integrations</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-2">ai:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-8">AI</span><span class="hl-1">)</span><br/><span class="hl-1"> };</span><br/><span class="hl-1">}</span>
150
+ </code><button type="button">Copy</button></pre>
151
+
152
+ <h3 id="6-clear-activity-titles" class="tsd-anchor-link">6. Clear Activity Titles<a href="#6-clear-activity-titles" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Make activity titles clear and actionable:</p>
153
+ <pre><code class="typescript"><span class="hl-7">// ❌ Vague</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Task</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Thing&quot;</span><span class="hl-1">,</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-7">// ✅ Clear</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Task</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Review pull request #123 for authentication fix&quot;</span><span class="hl-1">,</span><br/><span class="hl-1">});</span>
154
+ </code><button type="button">Copy</button></pre>
155
+
156
+ <hr>
157
+ <h2 id="next-steps" class="tsd-anchor-link">Next Steps<a href="#next-steps" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
158
+ <li><strong><a href="Built-in_Tools.html">Built-in Tools Guide</a></strong> - Learn about Plot, Store, AI, and more</li>
159
+ <li><strong><a href="Building_Custom_Tools.html">Building Custom Tools</a></strong> - Create reusable tools</li>
160
+ <li><strong><a href="Runtime_Environment.html">Runtime Environment</a></strong> - Understand execution constraints</li>
161
+ <li><strong><a href="Advanced.html">Advanced Topics</a></strong> - Complex patterns and techniques</li>
162
+ </ul>
163
+ </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#core-concepts"><span>Core <wbr/>Concepts</span></a><ul><li><a href="#table-of-contents"><span>Table of <wbr/>Contents</span></a></li><li><a href="#twists"><span>Twists</span></a></li><li><ul><li><a href="#what-is-a-twist"><span>What is a <wbr/>Twist?</span></a></li><li><a href="#twist-anatomy"><span>Twist <wbr/>Anatomy</span></a></li><li><a href="#when-to-use-twists"><span>When to <wbr/>Use <wbr/>Twists</span></a></li></ul></li><li><a href="#twist-tools"><span>Twist <wbr/>Tools</span></a></li><li><ul><li><a href="#types-of-tools"><span>Types of <wbr/>Tools</span></a></li><li><ul><li><a href="#1-built-in-tools"><span>1. <wbr/>Built-<wbr/>in <wbr/>Tools</span></a></li><li><a href="#2-custom-tools"><span>2. <wbr/>Custom <wbr/>Tools</span></a></li></ul></li><li><a href="#declaring-tool-dependencies"><span>Declaring <wbr/>Tool <wbr/>Dependencies</span></a></li><li><a href="#accessing-tools"><span>Accessing <wbr/>Tools</span></a></li><li><a href="#direct-access-methods"><span>Direct <wbr/>Access <wbr/>Methods</span></a></li></ul></li><li><a href="#priorities"><span>Priorities</span></a></li><li><ul><li><a href="#priority-hierarchy"><span>Priority <wbr/>Hierarchy</span></a></li><li><a href="#creating-priorities"><span>Creating <wbr/>Priorities</span></a></li><li><a href="#twist-activation"><span>Twist <wbr/>Activation</span></a></li></ul></li><li><a href="#activities"><span>Activities</span></a></li><li><ul><li><a href="#activity-types"><span>Activity <wbr/>Types</span></a></li><li><a href="#activity-properties"><span>Activity <wbr/>Properties</span></a></li><li><a href="#activity-links"><span>Activity <wbr/>Links</span></a></li></ul></li><li><a href="#lifecycle-methods"><span>Lifecycle <wbr/>Methods</span></a></li><li><ul><li><a href="#activatepriority"><span>activate(priority)</span></a></li><li><a href="#upgrade"><span>upgrade()</span></a></li><li><a href="#deactivate"><span>deactivate()</span></a></li></ul></li><li><a href="#best-practices"><span>Best <wbr/>Practices</span></a></li><li><ul><li><a href="#1-state-management"><span>1. <wbr/>State <wbr/>Management</span></a></li><li><a href="#2-error-handling"><span>2. <wbr/>Error <wbr/>Handling</span></a></li><li><a href="#3-batch-long-operations"><span>3. <wbr/>Batch <wbr/>Long <wbr/>Operations</span></a></li><li><a href="#4-type-safety"><span>4. <wbr/>Type <wbr/>Safety</span></a></li><li><a href="#5-tool-composition"><span>5. <wbr/>Tool <wbr/>Composition</span></a></li><li><a href="#6-clear-activity-titles"><span>6. <wbr/>Clear <wbr/>Activity <wbr/>Titles</span></a></li></ul></li><li><a href="#next-steps"><span>Next <wbr/>Steps</span></a></li></ul></div></details></div><div class="site-menu"><nav id="tsd-sidebar-links" class="tsd-navigation"><a href="https://plot.day" class="tsd-nav-link">Plot</a><a href="https://github.com/plotday/plot" class="tsd-nav-link">GitHub</a><a href="https://www.npmjs.com/package/@plotday/twister" class="tsd-nav-link">NPM</a></nav><nav class="tsd-navigation"><a href="../modules.html">Creating Plot Twists</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
@@ -0,0 +1,94 @@
1
+ <!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Getting Started | Creating Plot Twists</title><link rel="icon" href="../assets/favicon.svg" type="image/svg+xml"/><meta name="description" content="Documentation for Creating Plot Twists"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="/" class="title">Creating Plot Twists</a><div id="tsd-toolbar-links"><a href="https://plot.day">Plot</a><a href="https://github.com/plotday/plot">GitHub</a><a href="https://www.npmjs.com/package/@plotday/twister">NPM</a></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">Getting Started</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="getting-started-with-plot-twists" class="tsd-anchor-link">Getting Started with Plot Twists<a href="#getting-started-with-plot-twists" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p>This guide will walk you through creating your first Plot Twist. There are two ways to build twists: with natural language (no code) or with TypeScript code for maximum flexibility.</p>
2
+ <h2 id="choose-your-path" class="tsd-anchor-link">Choose Your Path<a href="#choose-your-path" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
3
+ <li><strong><a href="#no-code-twists">No-Code Twists</a></strong> - Perfect for non-developers or rapid prototyping</li>
4
+ <li><strong><a href="#developer-twists">Developer Twists</a></strong> - Full control with TypeScript</li>
5
+ </ul>
6
+ <hr>
7
+ <h2 id="no-code-twists" class="tsd-anchor-link">No-Code Twists<a href="#no-code-twists" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Create twists using natural language descriptions - no programming required!</p>
8
+ <h3 id="step-1-create-a-plot-twistmd-file" class="tsd-anchor-link">Step 1: Create a <a href="http://plot-twist.md">plot-twist.md</a> File<a href="#step-1-create-a-plot-twistmd-file" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Create a file named <code>plot-twist.md</code> in your project directory and describe what you want your twist to do:</p>
9
+ <pre><code class="markdown"><span class="hl-9"># My Calendar Twist</span><br/><br/><span class="hl-1">I want a twist that:</span><br/><br/><span class="hl-10">-</span><span class="hl-1"> Syncs my Google Calendar events into Plot as activities</span><br/><span class="hl-10">-</span><span class="hl-1"> Creates tasks for upcoming meetings</span><br/><span class="hl-10">-</span><span class="hl-1"> Sends me a reminder 10 minutes before each meeting</span><br/><span class="hl-10">-</span><span class="hl-1"> Updates activity status when meetings are completed</span>
10
+ </code><button type="button">Copy</button></pre>
11
+
12
+ <p><strong>Be specific about:</strong></p>
13
+ <ul>
14
+ <li><strong>Data sources</strong> - Which services to connect (Google Calendar, GitHub, Slack, etc.)</li>
15
+ <li><strong>Actions</strong> - What the twist should do (create tasks, send notifications, update status)</li>
16
+ <li><strong>Triggers</strong> - When actions should happen (on new events, on schedule, when activities change)</li>
17
+ </ul>
18
+ <h3 id="step-2-deploy-your-twist" class="tsd-anchor-link">Step 2: Deploy Your Twist<a href="#step-2-deploy-your-twist" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>You'll need a <a href="https://plot.day">Plot account</a> to deploy twists.</p>
19
+ <pre><code class="bash"><span class="hl-7"># Login to Plot</span><br/><span class="hl-6">npx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">login</span><br/><br/><span class="hl-7"># Deploy directly from your spec</span><br/><span class="hl-6">npx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">deploy</span>
20
+ </code><button type="button">Copy</button></pre>
21
+
22
+ <p>That's it! Your twist is now live in Plot.</p>
23
+ <h3 id="optional-generate-code-first" class="tsd-anchor-link">Optional: Generate Code First<a href="#optional-generate-code-first" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>If you want to review or customize the generated code before deploying:</p>
24
+ <pre><code class="bash"><span class="hl-7"># Generate TypeScript code from your spec</span><br/><span class="hl-6">npx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">generate</span><br/><br/><span class="hl-7"># Review and edit the generated src/index.ts</span><br/><span class="hl-7"># Then deploy</span><br/><span class="hl-6">npx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">deploy</span>
25
+ </code><button type="button">Copy</button></pre>
26
+
27
+ <p>The <code>generate</code> command creates a complete TypeScript twist that you can modify and extend.</p>
28
+ <hr>
29
+ <h2 id="developer-twists" class="tsd-anchor-link">Developer Twists<a href="#developer-twists" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Build twists with full control using TypeScript.</p>
30
+ <h3 id="step-1-create-a-new-twist-project" class="tsd-anchor-link">Step 1: Create a New Twist Project<a href="#step-1-create-a-new-twist-project" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Use the Plot CLI to scaffold a new twist:</p>
31
+ <pre><code class="bash"><span class="hl-6">npx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">create</span><br/><span class="hl-7"># or</span><br/><span class="hl-6">yarn</span><span class="hl-1"> </span><span class="hl-3">dlx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">create</span><br/><span class="hl-7"># or</span><br/><span class="hl-6">pnpm</span><span class="hl-1"> </span><span class="hl-3">dlx</span><span class="hl-1"> </span><span class="hl-3">@plotday/twister</span><span class="hl-1"> </span><span class="hl-3">create</span>
32
+ </code><button type="button">Copy</button></pre>
33
+
34
+ <p>You'll be prompted for:</p>
35
+ <ul>
36
+ <li><strong>Package name</strong> (kebab-case, e.g., <code>my-calendar-twist</code>)</li>
37
+ <li><strong>Display name</strong> (human-readable, e.g., &quot;My Calendar Twist&quot;)</li>
38
+ </ul>
39
+ <p>This creates a new directory with:</p>
40
+ <pre><code><span class="hl-2">my</span><span class="hl-1">-</span><span class="hl-2">calendar</span><span class="hl-1">-</span><span class="hl-2">twist</span><span class="hl-1">/</span><br/><span class="hl-1">├── </span><span class="hl-2">src</span><span class="hl-1">/</span><br/><span class="hl-1">│ └── </span><span class="hl-2">index</span><span class="hl-1">.</span><span class="hl-2">ts</span><span class="hl-1"> # </span><span class="hl-2">Your</span><span class="hl-1"> </span><span class="hl-2">twist</span><span class="hl-1"> </span><span class="hl-2">code</span><br/><span class="hl-1">├── </span><span class="hl-2">package</span><span class="hl-1">.</span><span class="hl-2">json</span><br/><span class="hl-1">├── </span><span class="hl-2">tsconfig</span><span class="hl-1">.</span><span class="hl-2">json</span><br/><span class="hl-1">└── </span><span class="hl-2">plot</span><span class="hl-1">-</span><span class="hl-2">twist</span><span class="hl-1">.</span><span class="hl-2">json</span><span class="hl-1"> # </span><span class="hl-2">Twist</span><span class="hl-1"> </span><span class="hl-2">configuration</span>
41
+ </code><button>Copy</button></pre>
42
+
43
+ <h3 id="step-2-implement-your-twist" class="tsd-anchor-link">Step 2: Implement Your Twist<a href="#step-2-implement-your-twist" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Edit <code>src/index.ts</code> to add your twist logic:</p>
44
+ <pre><code class="typescript"><span class="hl-0">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">type</span><span class="hl-1"> </span><span class="hl-2">Activity</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">Twist</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">type</span><span class="hl-1"> </span><span class="hl-2">Priority</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-0">type</span><span class="hl-1"> </span><span class="hl-2">ToolBuilder</span><span class="hl-1">,</span><br/><span class="hl-1">} </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&quot;@plotday/twister&quot;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">Plot</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&quot;@plotday/twister/tools/plot&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-0">default</span><span class="hl-1"> </span><span class="hl-4">class</span><span class="hl-1"> </span><span class="hl-5">MyTwist</span><span class="hl-1"> </span><span class="hl-4">extends</span><span class="hl-1"> </span><span class="hl-5">Twist</span><span class="hl-1">&lt;</span><span class="hl-5">MyTwist</span><span class="hl-1">&gt; {</span><br/><span class="hl-1"> </span><span class="hl-7">// Declare tool dependencies</span><br/><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">build</span><span class="hl-1">: </span><span class="hl-5">ToolBuilder</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">plot:</span><span class="hl-1"> </span><span class="hl-6">build</span><span class="hl-1">(</span><span class="hl-2">Plot</span><span class="hl-1">),</span><br/><span class="hl-1"> };</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Called when the twist is activated for a priority</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">activate</span><span class="hl-1">(</span><span class="hl-2">priority</span><span class="hl-1">: </span><span class="hl-5">Pick</span><span class="hl-1">&lt;</span><span class="hl-5">Priority</span><span class="hl-1">, </span><span class="hl-3">&quot;id&quot;</span><span class="hl-1">&gt;) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Note</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Welcome! Your twist is now active.&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> });</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Called when an activity is routed to this twist</span><br/><span class="hl-1"> </span><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-6">activity</span><span class="hl-1">(</span><span class="hl-2">activity</span><span class="hl-1">: </span><span class="hl-5">Activity</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&quot;Processing activity:&quot;</span><span class="hl-1">, </span><span class="hl-2">activity</span><span class="hl-1">.</span><span class="hl-2">title</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
45
+ </code><button type="button">Copy</button></pre>
46
+
47
+ <h3 id="step-3-test-locally" class="tsd-anchor-link">Step 3: Test Locally<a href="#step-3-test-locally" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Build and check for errors:</p>
48
+ <pre><code class="bash"><span class="hl-6">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">build</span><br/><span class="hl-7"># or</span><br/><span class="hl-6">pnpm</span><span class="hl-1"> </span><span class="hl-3">build</span>
49
+ </code><button type="button">Copy</button></pre>
50
+
51
+ <h3 id="step-4-deploy" class="tsd-anchor-link">Step 4: Deploy<a href="#step-4-deploy" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>You'll need a <a href="https://plot.day">Plot account</a> to deploy twists.</p>
52
+ <pre><code class="bash"><span class="hl-7"># Login to Plot</span><br/><span class="hl-6">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">plot</span><span class="hl-1"> </span><span class="hl-3">login</span><br/><br/><span class="hl-7"># Deploy your twist</span><br/><span class="hl-6">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">deploy</span>
53
+ </code><button type="button">Copy</button></pre>
54
+
55
+ <p>Your twist is now deployed and ready to activate in Plot!</p>
56
+ <hr>
57
+ <h2 id="understanding-the-project-structure" class="tsd-anchor-link">Understanding the Project Structure<a href="#understanding-the-project-structure" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="twist-file-srcindexts" class="tsd-anchor-link">Twist File (src/index.ts)<a href="#twist-file-srcindexts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Your twist extends the <code>Twist</code> class and implements:</p>
58
+ <ul>
59
+ <li><strong><code>build()</code></strong> - Declares tool dependencies</li>
60
+ <li><strong><code>activate()</code></strong> - Initialization when added to a priority</li>
61
+ <li><strong><code>deactivate()</code></strong> - Cleanup when removed from a priority</li>
62
+ <li><strong><code>upgrade()</code></strong> - Migration when deploying a new version</li>
63
+ </ul>
64
+ <h3 id="configuration-plot-twistjson" class="tsd-anchor-link">Configuration (plot-twist.json)<a href="#configuration-plot-twistjson" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Contains twist metadata:</p>
65
+ <pre><code class="json"><span class="hl-1">{</span><br/><span class="hl-1"> </span><span class="hl-11">&quot;name&quot;</span><span class="hl-1">: </span><span class="hl-3">&quot;my-calendar-twist&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-11">&quot;displayName&quot;</span><span class="hl-1">: </span><span class="hl-3">&quot;My Calendar Twist&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-11">&quot;version&quot;</span><span class="hl-1">: </span><span class="hl-3">&quot;1.0.0&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-11">&quot;description&quot;</span><span class="hl-1">: </span><span class="hl-3">&quot;Syncs calendar events to Plot&quot;</span><br/><span class="hl-1">}</span>
66
+ </code><button type="button">Copy</button></pre>
67
+
68
+ <h3 id="typescript-config-tsconfigjson" class="tsd-anchor-link">TypeScript Config (tsconfig.json)<a href="#typescript-config-tsconfigjson" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Extends the Twist Creator's base configuration:</p>
69
+ <pre><code class="json"><span class="hl-1">{</span><br/><span class="hl-1"> </span><span class="hl-11">&quot;extends&quot;</span><span class="hl-1">: </span><span class="hl-3">&quot;@plotday/twister/tsconfig.base.json&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-11">&quot;include&quot;</span><span class="hl-1">: [</span><span class="hl-3">&quot;src/*.ts&quot;</span><span class="hl-1">]</span><br/><span class="hl-1">}</span>
70
+ </code><button type="button">Copy</button></pre>
71
+
72
+ <hr>
73
+ <h2 id="next-steps" class="tsd-anchor-link">Next Steps<a href="#next-steps" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Now that you have a basic twist running, explore:</p>
74
+ <ul>
75
+ <li><strong><a href="Core_Concepts.html">Core Concepts</a></strong> - Understand twists, tools, and the Plot architecture</li>
76
+ <li><strong><a href="Built-in_Tools.html">Built-in Tools</a></strong> - Learn about Plot, Store, Integrations, AI, and more</li>
77
+ <li><strong><a href="Building_Custom_Tools.html">Building Custom Tools</a></strong> - Create your own reusable twist tools</li>
78
+ <li><strong><a href="Runtime_Environment.html">Runtime Environment</a></strong> - Understand execution constraints and optimization</li>
79
+ </ul>
80
+ <h2 id="common-first-tasks" class="tsd-anchor-link">Common First Tasks<a href="#common-first-tasks" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="creating-activities" class="tsd-anchor-link">Creating Activities<a href="#creating-activities" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Task</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;Review pull request&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">note:</span><span class="hl-1"> </span><span class="hl-3">&quot;Check the new authentication flow&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">links:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityLinkType</span><span class="hl-1">.</span><span class="hl-2">external</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">&quot;View PR&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">url:</span><span class="hl-1"> </span><span class="hl-3">&quot;https://github.com/org/repo/pull/123&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> ],</span><br/><span class="hl-1">});</span>
81
+ </code><button type="button">Copy</button></pre>
82
+
83
+ <h3 id="storing-data" class="tsd-anchor-link">Storing Data<a href="#storing-data" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-7">// Save</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;last_sync&quot;</span><span class="hl-1">, </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">().</span><span class="hl-6">toISOString</span><span class="hl-1">());</span><br/><br/><span class="hl-7">// Retrieve</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">lastSync</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">string</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;last_sync&quot;</span><span class="hl-1">);</span>
84
+ </code><button type="button">Copy</button></pre>
85
+
86
+ <h3 id="scheduling-tasks" class="tsd-anchor-link">Scheduling Tasks<a href="#scheduling-tasks" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="typescript"><span class="hl-7">// Run immediately</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;processData&quot;</span><span class="hl-1">);</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><br/><span class="hl-7">// Schedule for later</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">runAt:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">(</span><span class="hl-3">&quot;2025-02-01T10:00:00Z&quot;</span><span class="hl-1">),</span><br/><span class="hl-1">});</span>
87
+ </code><button type="button">Copy</button></pre>
88
+
89
+ <h2 id="need-help" class="tsd-anchor-link">Need Help?<a href="#need-help" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
90
+ <li><strong>Documentation</strong>: Continue reading the guides</li>
91
+ <li><strong>Examples</strong>: Check the <a href="https://github.com/plotday/plot/tree/main/twists">examples directory</a></li>
92
+ <li><strong>Issues</strong>: <a href="https://github.com/plotday/plot/issues">Report bugs or request features</a></li>
93
+ </ul>
94
+ </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#getting-started-with-plot-twists"><span>Getting <wbr/>Started with <wbr/>Plot <wbr/>Twists</span></a><ul><li><a href="#choose-your-path"><span>Choose <wbr/>Your <wbr/>Path</span></a></li><li><a href="#no-code-twists"><span>No-<wbr/>Code <wbr/>Twists</span></a></li><li><ul><li><a href="#step-1-create-a-plot-twistmd-file"><span>Step 1: <wbr/>Create a plot-<wbr/>twist.md <wbr/>File</span></a></li><li><a href="#step-2-deploy-your-twist"><span>Step 2: <wbr/>Deploy <wbr/>Your <wbr/>Twist</span></a></li><li><a href="#optional-generate-code-first"><span>Optional: <wbr/>Generate <wbr/>Code <wbr/>First</span></a></li></ul></li><li><a href="#developer-twists"><span>Developer <wbr/>Twists</span></a></li><li><ul><li><a href="#step-1-create-a-new-twist-project"><span>Step 1: <wbr/>Create a <wbr/>New <wbr/>Twist <wbr/>Project</span></a></li><li><a href="#step-2-implement-your-twist"><span>Step 2: <wbr/>Implement <wbr/>Your <wbr/>Twist</span></a></li><li><a href="#step-3-test-locally"><span>Step 3: <wbr/>Test <wbr/>Locally</span></a></li><li><a href="#step-4-deploy"><span>Step 4: <wbr/>Deploy</span></a></li></ul></li><li><a href="#understanding-the-project-structure"><span>Understanding the <wbr/>Project <wbr/>Structure</span></a></li><li><ul><li><a href="#twist-file-srcindexts"><span>Twist <wbr/>File (src/index.ts)</span></a></li><li><a href="#configuration-plot-twistjson"><span>Configuration (plot-<wbr/>twist.json)</span></a></li><li><a href="#typescript-config-tsconfigjson"><span>Type<wbr/>Script <wbr/>Config (tsconfig.json)</span></a></li></ul></li><li><a href="#next-steps"><span>Next <wbr/>Steps</span></a></li><li><a href="#common-first-tasks"><span>Common <wbr/>First <wbr/>Tasks</span></a></li><li><ul><li><a href="#creating-activities"><span>Creating <wbr/>Activities</span></a></li><li><a href="#storing-data"><span>Storing <wbr/>Data</span></a></li><li><a href="#scheduling-tasks"><span>Scheduling <wbr/>Tasks</span></a></li></ul></li><li><a href="#need-help"><span>Need <wbr/>Help?</span></a></li></ul></div></details></div><div class="site-menu"><nav id="tsd-sidebar-links" class="tsd-navigation"><a href="https://plot.day" class="tsd-nav-link">Plot</a><a href="https://github.com/plotday/plot" class="tsd-nav-link">GitHub</a><a href="https://www.npmjs.com/package/@plotday/twister" class="tsd-nav-link">NPM</a></nav><nav class="tsd-navigation"><a href="../modules.html">Creating Plot Twists</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>