@plotday/twister 0.45.0 → 0.46.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.
@@ -1 +1 @@
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>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"><h1>Creating Plot Twists</h1></div><h2>Hierarchy Summary</h2><ul class="tsd-full-hierarchy"><li data-refl="125" id="tool.ITool"><a href="classes/tool.ITool.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>ITool</a><ul><li data-refl="128" id="tool.Tool"><a href="classes/tool.Tool.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Tool</a></li><li data-refl="544" id="tools/twists.Twists"><a href="classes/tools_twists.Twists.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Twists</a></li><li data-refl="574" id="tools/ai.AI"><a href="classes/tools_ai.AI.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>AI</a></li><li data-refl="765" id="tools/callbacks.Callbacks"><a href="classes/tools_callbacks.Callbacks.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Callbacks</a></li><li data-refl="840" id="tools/integrations.Integrations"><a href="classes/tools_integrations.Integrations.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Integrations</a></li><li data-refl="918" id="tools/network.Network"><a href="classes/tools_network.Network.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Network</a></li><li data-refl="990" id="tools/plot.Plot"><a href="classes/tools_plot.Plot.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Plot</a></li><li data-refl="1116" id="tools/store.Store"><a href="classes/tools_store.Store.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Store</a></li><li data-refl="1137" id="tools/tasks.Tasks"><a href="classes/tools_tasks.Tasks.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Tasks</a></li><li data-refl="1568" id="index.Imap"><a href="classes/index.Imap.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Imap</a></li><li data-refl="1633" id="index.Smtp"><a href="classes/index.Smtp.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Smtp</a></li><li data-refl="1687" id="index.Options"><a href="classes/index.Options.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Options</a></li></ul></li></ul><ul class="tsd-full-hierarchy"><li data-refl="9" id="twist.Twist"><a href="classes/twist.Twist.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Twist</a><ul><li data-refl="1203" id="index.Connector"><a href="classes/index.Connector.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Connector</a></li></ul></li></ul></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></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>
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>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"><h1>Creating Plot Twists</h1></div><h2>Hierarchy Summary</h2><ul class="tsd-full-hierarchy"><li data-refl="126" id="tool.ITool"><a href="classes/tool.ITool.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>ITool</a><ul><li data-refl="129" id="tool.Tool"><a href="classes/tool.Tool.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Tool</a></li><li data-refl="545" id="tools/twists.Twists"><a href="classes/tools_twists.Twists.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Twists</a></li><li data-refl="575" id="tools/ai.AI"><a href="classes/tools_ai.AI.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>AI</a></li><li data-refl="766" id="tools/callbacks.Callbacks"><a href="classes/tools_callbacks.Callbacks.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Callbacks</a></li><li data-refl="841" id="tools/integrations.Integrations"><a href="classes/tools_integrations.Integrations.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Integrations</a></li><li data-refl="919" id="tools/network.Network"><a href="classes/tools_network.Network.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Network</a></li><li data-refl="991" id="tools/plot.Plot"><a href="classes/tools_plot.Plot.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Plot</a></li><li data-refl="1117" id="tools/store.Store"><a href="classes/tools_store.Store.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Store</a></li><li data-refl="1138" id="tools/tasks.Tasks"><a href="classes/tools_tasks.Tasks.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Tasks</a></li><li data-refl="1570" id="index.Imap"><a href="classes/index.Imap.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Imap</a></li><li data-refl="1635" id="index.Smtp"><a href="classes/index.Smtp.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Smtp</a></li><li data-refl="1689" id="index.Options"><a href="classes/index.Options.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Options</a></li></ul></li></ul><ul class="tsd-full-hierarchy"><li data-refl="9" id="twist.Twist"><a href="classes/twist.Twist.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Twist</a><ul><li data-refl="1204" id="index.Connector"><a href="classes/index.Connector.html"><svg class="tsd-kind-icon" viewBox="0 0 24 24" aria-label="Class"><use href="assets/icons.svg#icon-128"></use></svg>Connector</a></li></ul></li></ul></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></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>
@@ -556,19 +556,39 @@ The `activity.source` field is the idempotency key for automatic upserts. Use a
556
556
  <provider>:<namespace>:<id> — When provider has multiple entity types
557
557
  ```
558
558
 
559
- Examples from existing connectors:
559
+ ### Source identifier uniqueness (CRITICAL)
560
+
561
+ `source` is the **cross-user deduplication key** for the Plot runtime. Two instances of the same connector that emit the same `source` string will **converge on a single shared thread** across users — that's how two users on the same Gmail message see one shared thread rather than two parallel ones.
562
+
563
+ This means your `source` must be globally unique for the logical external item — not merely unique within a single user's account. Before committing a source pattern, ask yourself: *"Could two different users' connector instances emit this exact string for different external items?"* If yes, you must include a qualifier (workspace, tenant, mailbox, project, …).
564
+
565
+ Safe patterns (globally unique external ids):
566
+ ```
567
+ linear:issue:<uuid> — Linear issue UUIDs are globally unique
568
+ github:<owner>/<repo>/issue:<number> — Scoped by owner+repo
569
+ google-chat:<spaceId>:thread:<threadKey> — Space id globally unique
570
+ ms-teams:channel:<channelId>:message:<id> — Teams channel id globally unique
571
+ ms-teams:dm:<chatId> — Chat ids globally unique
572
+ https://mail.google.com/mail/u/0/#inbox/<threadId> — Gmail thread id globally unique
573
+ ```
574
+
575
+ Patterns that need disambiguation:
560
576
  ```
561
- linear:issue:<issueId>
562
- asana:task:<taskGid>
563
- jira:<cloudId>:issue:<issueId> Uses immutable ID, NOT mutable key like "PROJ-123"
564
- google-calendar:<eventId>
565
- outlook-calendar:<eventId>
566
- google-drive:file:<fileId>
567
- https://mail.google.com/mail/u/0/#inbox/<threadId> — Gmail uses full URL
568
- https://slack.com/app_redirect?channel=<id>&message_ts=<ts> — Slack uses full URL
577
+ attio:<workspaceId>:<type>:<recordId> — Attio record ids are workspace-scoped
578
+ posthog:<projectId>:person:<distinctId> — distinct_id is project-scoped (often just an email)
579
+ outlook-calendar:<mailboxId>:<eventId> Graph event ids are mailbox-local
580
+ fellow:<tenantId>:note:<id> — Fellow ids are tenant-scoped
569
581
  ```
570
582
 
571
- **Critical:** For services with mutable identifiers (like Jira where issue keys change on project move), use the immutable ID in `source` and store the mutable key in `meta` only.
583
+ **If you're adding a new connector, pick a source format that encodes the tenant/workspace/mailbox upfront.** Retrofits are possible but require a backfill migration.
584
+
585
+ **Mutable IDs:** For services where identifiers can change (like Jira issue keys that change on project move), use the immutable ID in `source` and store the mutable key in `meta` only.
586
+
587
+ ### Attestation-based visibility for shared threads
588
+
589
+ When your connector populates `thread.contacts` from an external item's recipients, listing someone there does NOT automatically admit them to the thread. The runtime requires that each user's own connector instance independently sync the item (proof that it's in their authenticated account) before they gain a `thread_priority` row. Users whose own sync arrives before any other user has attested them land in `thread.pending_contacts` and are promoted to `thread.contacts` on the next attester's sync.
590
+
591
+ You don't need to do anything special for this — just continue to populate `contacts` with every recipient you see. The runtime's `upsert_thread` enforces attestation; connectors can treat visibility as a server-side concern.
572
592
 
573
593
  ## Note Key Conventions
574
594
 
@@ -98,7 +98,11 @@ The `source` field should be:
98
98
 
99
99
  - A canonical URL from the external system (preferred)
100
100
  - A stable identifier in a namespaced format (e.g., `gmail:thread-id-123`)
101
- - Unique within the priority tree
101
+ - **Globally unique for the logical external item** — see "Source identifier uniqueness" below
102
+
103
+ > **Cross-user dedup:** Two instances of the same connector (run by two different Plot users) that emit the same `source` for the same external item will converge on a **single shared thread**. This is how two users on the same Gmail message, calendar event, or Linear issue see one thread rather than two.
104
+ >
105
+ > This means `source` must not merely be unique within one user's account — it must be globally unique for the item. If an external id is workspace- or tenant-scoped (Attio record ids, PostHog distinct_ids, Outlook event ids, Fellow note ids, etc.), include the workspace/tenant/mailbox id as a qualifier: `attio:<workspaceId>:person:<recordId>`, not `attio:person:<recordId>`. See `connectors/AGENTS.md` → "Source identifier uniqueness" for the full guidance.
102
106
 
103
107
  ```typescript
104
108
  // Activity.source field definition
@@ -4,6 +4,6 @@
4
4
  * This file is auto-generated during build. Do not edit manually.
5
5
  * Generated from: prebuild.ts
6
6
  */
7
- declare const _default: "import { type Action, type Actor, type ActorId, type Link, type Note, type Thread, Uuid } from \"./plot\";\nimport type { Tag } from \"./tag\";\nimport { type ITool } from \"./tool\";\nimport type { Callback } from \"./tools/callbacks\";\nimport type { Serializable } from \"./utils/serializable\";\nimport type { InferTools, ToolBuilder, ToolShed } from \"./utils/types\";\n\n/**\n * Base class for all twists.\n *\n * A twist is installed at the workspace level and is owned by a single user\n * (see `this.userId`). It has no inherent priority scope: threads, notes, and\n * links it creates are filed against the owner's priorities, with automatic\n * priority matching when no explicit target is provided.\n *\n * Override `build()` to declare tool dependencies and lifecycle methods to\n * handle events.\n *\n * @example\n * ```typescript\n * class FlatteringTwist extends Twist<FlatteringTwist> {\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * };\n * }\n *\n * async activate() {\n * await this.tools.plot.createThread({\n * title: \"Hello, good looking!\",\n * });\n * }\n * }\n * ```\n */\nexport abstract class Twist<TSelf> {\n /**\n * The user ID (`twist_instance.owner_id`) that installed this twist.\n * Populated by the runtime before any lifecycle method runs.\n */\n protected userId!: Uuid;\n\n constructor(protected id: Uuid, private toolShed: ToolShed) {}\n\n /**\n * Gets the initialized tools for this twist.\n * @throws Error if called before initialization is complete\n */\n protected get tools(): InferTools<TSelf> {\n return this.toolShed.getTools<InferTools<TSelf>>();\n }\n\n /**\n * Declares tool dependencies for this twist.\n * Return an object mapping tool names to build() promises.\n *\n * @param build - The build function to use for declaring dependencies\n * @returns Object mapping tool names to tool promises\n *\n * @example\n * ```typescript\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * calendar: build(GoogleCalendar, { apiKey: \"...\" }),\n * };\n * }\n * ```\n */\n abstract build(build: ToolBuilder): Record<string, Promise<ITool>>;\n\n /**\n * Creates a persistent callback to a method on this twist.\n *\n * ExtraArgs are strongly typed to match the method's signature. They must be serializable.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass (type-checked, must be serializable)\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.callback(this.onWebhook, \"calendar\", 123);\n * ```\n */\n protected callback<\n TArgs extends Serializable[],\n Fn extends (...args: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n // Overload when caller provides the first argument\n protected callback<\n TArgs extends Serializable[],\n Fn extends (arg1: any, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n protected async callback<\n TArgs extends Serializable[],\n Fn extends (...args: any[]) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Like callback(), but for an Action, which receives the action as the first argument.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass after the action\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.actionCallback(this.doSomething, 123);\n * const action: Action = {\n * type: ActionType.callback,\n * title: \"Do Something\",\n * callback,\n * };\n * ```\n */\n protected async actionCallback<\n TArgs extends Serializable[],\n Fn extends (action: Action, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Deletes a specific callback by its token.\n *\n * @param token - The callback token to delete\n * @returns Promise that resolves when the callback is deleted\n */\n protected async deleteCallback(token: Callback): Promise<void> {\n return this.tools.callbacks.delete(token);\n }\n\n /**\n * Deletes all callbacks for this twist.\n *\n * @returns Promise that resolves when all callbacks are deleted\n */\n protected async deleteAllCallbacks(): Promise<void> {\n return this.tools.callbacks.deleteAll();\n }\n\n /**\n * Executes a callback by its token inline in the current execution.\n *\n * **Use `this.runTask()` instead for batch continuations and long-running work.**\n * `this.run()` executes inline, sharing the current request count (~1000 limit)\n * and blocking the HTTP response. This causes timeouts when used in lifecycle\n * methods like `onChannelEnabled` or `syncBatch` continuations.\n *\n * `this.run()` is appropriate when you need the callback's **return value** \u2014\n * e.g., running a parent callback token that returns data. For fire-and-forget\n * work, always prefer `this.runTask()`.\n *\n * @param token - The callback token to execute\n * @param args - Optional arguments to pass to the callback\n * @returns Promise resolving to the callback result\n */\n protected async run(token: Callback, ...args: []): Promise<any> {\n return this.tools.callbacks.run(token, ...args);\n }\n\n /**\n * Retrieves a value from persistent storage by key.\n *\n * Values are automatically deserialized using SuperJSON, which\n * properly restores Date objects, Maps, Sets, and other complex types.\n *\n * @template T - The expected type of the stored value (must be Serializable)\n * @param key - The storage key to retrieve\n * @returns Promise resolving to the stored value or null\n */\n protected async get<T extends import(\"./index\").Serializable>(\n key: string\n ): Promise<T | null> {\n return this.tools.store.get(key);\n }\n\n /**\n * Stores a value in persistent storage.\n *\n * The value will be serialized using SuperJSON and stored persistently.\n * SuperJSON automatically handles Date objects, Maps, Sets, undefined values,\n * and other complex types that standard JSON doesn't support.\n *\n * **Important**: Functions and Symbols cannot be stored.\n * **For function references**: Use callbacks instead of storing functions directly.\n *\n * @example\n * ```typescript\n * // \u2705 Date objects are preserved\n * await this.set(\"sync_state\", {\n * lastSync: new Date(),\n * minDate: new Date(2024, 0, 1)\n * });\n *\n * // \u2705 undefined is now supported\n * await this.set(\"data\", { name: \"test\", optional: undefined });\n *\n * // \u274C WRONG: Cannot store functions directly\n * await this.set(\"handler\", this.myHandler);\n *\n * // \u2705 CORRECT: Create a callback token first\n * const token = await this.callback(this.myHandler, \"arg1\", \"arg2\");\n * await this.set(\"handler_token\", token);\n *\n * // Later, execute the callback\n * const token = await this.get<string>(\"handler_token\");\n * await this.run(token, args);\n * ```\n *\n * @template T - The type of value being stored (must be Serializable)\n * @param key - The storage key to use\n * @param value - The value to store (must be SuperJSON-serializable)\n * @returns Promise that resolves when the value is stored\n */\n protected async set<T extends import(\"./index\").Serializable>(\n key: string,\n value: T\n ): Promise<void> {\n return this.tools.store.set(key, value);\n }\n\n /**\n * Removes a specific key from persistent storage.\n *\n * @param key - The storage key to remove\n * @returns Promise that resolves when the key is removed\n */\n protected async clear(key: string): Promise<void> {\n return this.tools.store.clear(key);\n }\n\n /**\n * Removes all keys from this twist's storage.\n *\n * @returns Promise that resolves when all keys are removed\n */\n protected async clearAll(): Promise<void> {\n return this.tools.store.clearAll();\n }\n\n /**\n * Queues a callback to execute in a separate worker context.\n *\n * @param callback - The callback token created with `this.callback()`\n * @param options - Optional configuration for the execution\n * @param options.runAt - If provided, schedules execution at this time; otherwise runs immediately\n * @returns Promise resolving to a cancellation token (only for scheduled executions)\n */\n protected async runTask(\n callback: Callback,\n options?: { runAt?: Date }\n ): Promise<string | void> {\n return this.tools.tasks.runTask(callback, options);\n }\n\n /**\n * Cancels a previously scheduled execution.\n *\n * @param token - The cancellation token returned by runTask() with runAt option\n * @returns Promise that resolves when the cancellation is processed\n */\n protected async cancelTask(token: string): Promise<void> {\n return this.tools.tasks.cancelTask(token);\n }\n\n /**\n * Cancels all scheduled executions for this twist.\n *\n * @returns Promise that resolves when all cancellations are processed\n */\n protected async cancelAllTasks(): Promise<void> {\n return this.tools.tasks.cancelAllTasks();\n }\n\n /**\n * Called when the twist is installed by a user.\n *\n * This method should contain initialization logic such as seeding\n * initial threads, configuring webhooks, or establishing external\n * connections. When it runs, `this.userId` is already populated with\n * the installing user's ID.\n *\n * @param context - Optional context containing the actor who triggered activation\n * @returns Promise that resolves when activation is complete\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n activate(context?: { actor: Actor }): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a new version of the twist is deployed.\n *\n * This method should contain migration logic for updating old data structures\n * or setting up new resources that weren't needed by the previous version.\n * It is called once per active twist_instance with the new version.\n *\n * @returns Promise that resolves when upgrade is complete\n */\n upgrade(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist's options configuration changes.\n *\n * Override to react to option changes, e.g. archiving items when a sync\n * type is toggled off, or starting sync when a type is toggled on.\n *\n * @param oldOptions - The previously resolved options\n * @param newOptions - The newly resolved options\n * @returns Promise that resolves when the change is handled\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onOptionsChanged(\n oldOptions: Record<string, any>,\n newOptions: Record<string, any>\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist is removed from a priority.\n *\n * This method should contain cleanup logic such as removing webhooks,\n * cleaning up external resources, or performing final data operations.\n *\n * @returns Promise that resolves when deactivation is complete\n */\n deactivate(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a thread created by this twist is updated.\n * Override to implement two-way sync with an external system.\n *\n * @param thread - The updated thread\n * @param changes - Tag additions and removals on the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onThreadUpdated(\n thread: Thread,\n changes: {\n tagsAdded: Record<Tag, ActorId[]>;\n tagsRemoved: Record<Tag, ActorId[]>;\n }\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread created by this twist.\n * Override to implement two-way sync (e.g. syncing notes as comments).\n *\n * Notes created by the twist itself are filtered out to prevent loops.\n *\n * Returning a string sets the note's `key` for future upsert matching,\n * linking the Plot note to its external counterpart so that subsequent\n * syncs (reactions, edits) update the existing note instead of creating duplicates.\n *\n * @param note - The newly created note\n * @returns Optional note key for external deduplication\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onNoteCreated(note: Note, ...args: any[]): Promise<string | void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link is created in a connected source channel.\n * Requires `link: true` in Plot options.\n *\n * @param link - The newly created link\n * @param notes - Notes on the link's thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkCreated(link: Link, notes: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link in a connected source channel is updated.\n * Requires `link: true` in Plot options.\n *\n * @param link - The updated link\n * @param notes - Notes on the link's thread (optional)\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkUpdated(link: Link, notes?: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread with a link from a connected channel.\n * Requires `link: true` in Plot options.\n *\n * @param note - The newly created note\n * @param link - The link associated with the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkNoteCreated(note: Note, link: Link): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Waits for tool initialization to complete.\n * Called automatically by the entrypoint before lifecycle methods.\n * @internal\n */\n async waitForReady(): Promise<void> {\n await this.toolShed.waitForReady();\n }\n}\n";
7
+ declare const _default: "import { type Action, type Actor, type ActorId, type Link, type Note, type Thread, Uuid } from \"./plot\";\nimport type { Tag } from \"./tag\";\nimport { type ITool } from \"./tool\";\nimport type { Callback } from \"./tools/callbacks\";\nimport type { Serializable } from \"./utils/serializable\";\nimport type { InferTools, ToolBuilder, ToolShed } from \"./utils/types\";\n\n/**\n * Base class for all twists.\n *\n * A twist is installed at the workspace level and is owned by a single user\n * (see `this.userId`). It has no inherent priority scope: threads, notes, and\n * links it creates are filed against the owner's priorities, with automatic\n * priority matching when no explicit target is provided.\n *\n * Override `build()` to declare tool dependencies and lifecycle methods to\n * handle events.\n *\n * @example\n * ```typescript\n * class FlatteringTwist extends Twist<FlatteringTwist> {\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * };\n * }\n *\n * async activate() {\n * await this.tools.plot.createThread({\n * title: \"Hello, good looking!\",\n * });\n * }\n * }\n * ```\n */\nexport abstract class Twist<TSelf> {\n /**\n * When `true`, users may install multiple instances of this twist within\n * the same scope (personal workspace or team). Each instance must have a\n * distinct name.\n *\n * Defaults to `false` (single instance per scope).\n *\n * @example\n * ```typescript\n * class WorkflowTwist extends Twist<WorkflowTwist> {\n * static readonly multipleInstances = true;\n * // ...\n * }\n * ```\n */\n static readonly multipleInstances?: boolean;\n\n /**\n * The user ID (`twist_instance.owner_id`) that installed this twist.\n * Populated by the runtime before any lifecycle method runs.\n */\n protected userId!: Uuid;\n\n constructor(protected id: Uuid, private toolShed: ToolShed) {}\n\n /**\n * Gets the initialized tools for this twist.\n * @throws Error if called before initialization is complete\n */\n protected get tools(): InferTools<TSelf> {\n return this.toolShed.getTools<InferTools<TSelf>>();\n }\n\n /**\n * Declares tool dependencies for this twist.\n * Return an object mapping tool names to build() promises.\n *\n * @param build - The build function to use for declaring dependencies\n * @returns Object mapping tool names to tool promises\n *\n * @example\n * ```typescript\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * calendar: build(GoogleCalendar, { apiKey: \"...\" }),\n * };\n * }\n * ```\n */\n abstract build(build: ToolBuilder): Record<string, Promise<ITool>>;\n\n /**\n * Creates a persistent callback to a method on this twist.\n *\n * ExtraArgs are strongly typed to match the method's signature. They must be serializable.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass (type-checked, must be serializable)\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.callback(this.onWebhook, \"calendar\", 123);\n * ```\n */\n protected callback<\n TArgs extends Serializable[],\n Fn extends (...args: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n // Overload when caller provides the first argument\n protected callback<\n TArgs extends Serializable[],\n Fn extends (arg1: any, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n protected async callback<\n TArgs extends Serializable[],\n Fn extends (...args: any[]) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Like callback(), but for an Action, which receives the action as the first argument.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass after the action\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.actionCallback(this.doSomething, 123);\n * const action: Action = {\n * type: ActionType.callback,\n * title: \"Do Something\",\n * callback,\n * };\n * ```\n */\n protected async actionCallback<\n TArgs extends Serializable[],\n Fn extends (action: Action, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Deletes a specific callback by its token.\n *\n * @param token - The callback token to delete\n * @returns Promise that resolves when the callback is deleted\n */\n protected async deleteCallback(token: Callback): Promise<void> {\n return this.tools.callbacks.delete(token);\n }\n\n /**\n * Deletes all callbacks for this twist.\n *\n * @returns Promise that resolves when all callbacks are deleted\n */\n protected async deleteAllCallbacks(): Promise<void> {\n return this.tools.callbacks.deleteAll();\n }\n\n /**\n * Executes a callback by its token inline in the current execution.\n *\n * **Use `this.runTask()` instead for batch continuations and long-running work.**\n * `this.run()` executes inline, sharing the current request count (~1000 limit)\n * and blocking the HTTP response. This causes timeouts when used in lifecycle\n * methods like `onChannelEnabled` or `syncBatch` continuations.\n *\n * `this.run()` is appropriate when you need the callback's **return value** \u2014\n * e.g., running a parent callback token that returns data. For fire-and-forget\n * work, always prefer `this.runTask()`.\n *\n * @param token - The callback token to execute\n * @param args - Optional arguments to pass to the callback\n * @returns Promise resolving to the callback result\n */\n protected async run(token: Callback, ...args: []): Promise<any> {\n return this.tools.callbacks.run(token, ...args);\n }\n\n /**\n * Retrieves a value from persistent storage by key.\n *\n * Values are automatically deserialized using SuperJSON, which\n * properly restores Date objects, Maps, Sets, and other complex types.\n *\n * @template T - The expected type of the stored value (must be Serializable)\n * @param key - The storage key to retrieve\n * @returns Promise resolving to the stored value or null\n */\n protected async get<T extends import(\"./index\").Serializable>(\n key: string\n ): Promise<T | null> {\n return this.tools.store.get(key);\n }\n\n /**\n * Stores a value in persistent storage.\n *\n * The value will be serialized using SuperJSON and stored persistently.\n * SuperJSON automatically handles Date objects, Maps, Sets, undefined values,\n * and other complex types that standard JSON doesn't support.\n *\n * **Important**: Functions and Symbols cannot be stored.\n * **For function references**: Use callbacks instead of storing functions directly.\n *\n * @example\n * ```typescript\n * // \u2705 Date objects are preserved\n * await this.set(\"sync_state\", {\n * lastSync: new Date(),\n * minDate: new Date(2024, 0, 1)\n * });\n *\n * // \u2705 undefined is now supported\n * await this.set(\"data\", { name: \"test\", optional: undefined });\n *\n * // \u274C WRONG: Cannot store functions directly\n * await this.set(\"handler\", this.myHandler);\n *\n * // \u2705 CORRECT: Create a callback token first\n * const token = await this.callback(this.myHandler, \"arg1\", \"arg2\");\n * await this.set(\"handler_token\", token);\n *\n * // Later, execute the callback\n * const token = await this.get<string>(\"handler_token\");\n * await this.run(token, args);\n * ```\n *\n * @template T - The type of value being stored (must be Serializable)\n * @param key - The storage key to use\n * @param value - The value to store (must be SuperJSON-serializable)\n * @returns Promise that resolves when the value is stored\n */\n protected async set<T extends import(\"./index\").Serializable>(\n key: string,\n value: T\n ): Promise<void> {\n return this.tools.store.set(key, value);\n }\n\n /**\n * Removes a specific key from persistent storage.\n *\n * @param key - The storage key to remove\n * @returns Promise that resolves when the key is removed\n */\n protected async clear(key: string): Promise<void> {\n return this.tools.store.clear(key);\n }\n\n /**\n * Removes all keys from this twist's storage.\n *\n * @returns Promise that resolves when all keys are removed\n */\n protected async clearAll(): Promise<void> {\n return this.tools.store.clearAll();\n }\n\n /**\n * Queues a callback to execute in a separate worker context.\n *\n * @param callback - The callback token created with `this.callback()`\n * @param options - Optional configuration for the execution\n * @param options.runAt - If provided, schedules execution at this time; otherwise runs immediately\n * @returns Promise resolving to a cancellation token (only for scheduled executions)\n */\n protected async runTask(\n callback: Callback,\n options?: { runAt?: Date }\n ): Promise<string | void> {\n return this.tools.tasks.runTask(callback, options);\n }\n\n /**\n * Cancels a previously scheduled execution.\n *\n * @param token - The cancellation token returned by runTask() with runAt option\n * @returns Promise that resolves when the cancellation is processed\n */\n protected async cancelTask(token: string): Promise<void> {\n return this.tools.tasks.cancelTask(token);\n }\n\n /**\n * Cancels all scheduled executions for this twist.\n *\n * @returns Promise that resolves when all cancellations are processed\n */\n protected async cancelAllTasks(): Promise<void> {\n return this.tools.tasks.cancelAllTasks();\n }\n\n /**\n * Called when the twist is installed by a user.\n *\n * This method should contain initialization logic such as seeding\n * initial threads, configuring webhooks, or establishing external\n * connections. When it runs, `this.userId` is already populated with\n * the installing user's ID.\n *\n * @param context - Optional context containing the actor who triggered activation\n * @returns Promise that resolves when activation is complete\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n activate(context?: { actor: Actor }): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a new version of the twist is deployed.\n *\n * This method should contain migration logic for updating old data structures\n * or setting up new resources that weren't needed by the previous version.\n * It is called once per active twist_instance with the new version.\n *\n * @returns Promise that resolves when upgrade is complete\n */\n upgrade(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist's options configuration changes.\n *\n * Override to react to option changes, e.g. archiving items when a sync\n * type is toggled off, or starting sync when a type is toggled on.\n *\n * @param oldOptions - The previously resolved options\n * @param newOptions - The newly resolved options\n * @returns Promise that resolves when the change is handled\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onOptionsChanged(\n oldOptions: Record<string, any>,\n newOptions: Record<string, any>\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist is uninstalled.\n *\n * This method should contain cleanup logic such as removing webhooks,\n * cleaning up external resources, or performing final data operations.\n *\n * @returns Promise that resolves when deactivation is complete\n */\n deactivate(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a thread created by this twist is updated.\n * Override to implement two-way sync with an external system.\n *\n * @param thread - The updated thread\n * @param changes - Tag additions and removals on the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onThreadUpdated(\n thread: Thread,\n changes: {\n tagsAdded: Record<Tag, ActorId[]>;\n tagsRemoved: Record<Tag, ActorId[]>;\n }\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread created by this twist.\n * Override to implement two-way sync (e.g. syncing notes as comments).\n *\n * Notes created by the twist itself are filtered out to prevent loops.\n *\n * Returning a string sets the note's `key` for future upsert matching,\n * linking the Plot note to its external counterpart so that subsequent\n * syncs (reactions, edits) update the existing note instead of creating duplicates.\n *\n * @param note - The newly created note\n * @returns Optional note key for external deduplication\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onNoteCreated(note: Note, ...args: any[]): Promise<string | void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link is created in a connected source channel.\n * Requires `link: true` in Plot options.\n *\n * @param link - The newly created link\n * @param notes - Notes on the link's thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkCreated(link: Link, notes: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link in a connected source channel is updated.\n * Requires `link: true` in Plot options.\n *\n * @param link - The updated link\n * @param notes - Notes on the link's thread (optional)\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkUpdated(link: Link, notes?: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread with a link from a connected channel.\n * Requires `link: true` in Plot options.\n *\n * @param note - The newly created note\n * @param link - The link associated with the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkNoteCreated(note: Note, link: Link): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Waits for tool initialization to complete.\n * Called automatically by the entrypoint before lifecycle methods.\n * @internal\n */\n async waitForReady(): Promise<void> {\n await this.toolShed.waitForReady();\n }\n}\n";
8
8
  export default _default;
9
9
  //# sourceMappingURL=twist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"twist.d.ts","sourceRoot":"","sources":["../../src/llm-docs/twist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;wBAEY,shcAA6/b;AAA5gc,wBAA6gc"}
1
+ {"version":3,"file":"twist.d.ts","sourceRoot":"","sources":["../../src/llm-docs/twist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;wBAEY,2+cAAk9c;AAAj+c,wBAAk+c"}
@@ -4,5 +4,5 @@
4
4
  * This file is auto-generated during build. Do not edit manually.
5
5
  * Generated from: prebuild.ts
6
6
  */
7
- export default "import { type Action, type Actor, type ActorId, type Link, type Note, type Thread, Uuid } from \"./plot\";\nimport type { Tag } from \"./tag\";\nimport { type ITool } from \"./tool\";\nimport type { Callback } from \"./tools/callbacks\";\nimport type { Serializable } from \"./utils/serializable\";\nimport type { InferTools, ToolBuilder, ToolShed } from \"./utils/types\";\n\n/**\n * Base class for all twists.\n *\n * A twist is installed at the workspace level and is owned by a single user\n * (see `this.userId`). It has no inherent priority scope: threads, notes, and\n * links it creates are filed against the owner's priorities, with automatic\n * priority matching when no explicit target is provided.\n *\n * Override `build()` to declare tool dependencies and lifecycle methods to\n * handle events.\n *\n * @example\n * ```typescript\n * class FlatteringTwist extends Twist<FlatteringTwist> {\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * };\n * }\n *\n * async activate() {\n * await this.tools.plot.createThread({\n * title: \"Hello, good looking!\",\n * });\n * }\n * }\n * ```\n */\nexport abstract class Twist<TSelf> {\n /**\n * The user ID (`twist_instance.owner_id`) that installed this twist.\n * Populated by the runtime before any lifecycle method runs.\n */\n protected userId!: Uuid;\n\n constructor(protected id: Uuid, private toolShed: ToolShed) {}\n\n /**\n * Gets the initialized tools for this twist.\n * @throws Error if called before initialization is complete\n */\n protected get tools(): InferTools<TSelf> {\n return this.toolShed.getTools<InferTools<TSelf>>();\n }\n\n /**\n * Declares tool dependencies for this twist.\n * Return an object mapping tool names to build() promises.\n *\n * @param build - The build function to use for declaring dependencies\n * @returns Object mapping tool names to tool promises\n *\n * @example\n * ```typescript\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * calendar: build(GoogleCalendar, { apiKey: \"...\" }),\n * };\n * }\n * ```\n */\n abstract build(build: ToolBuilder): Record<string, Promise<ITool>>;\n\n /**\n * Creates a persistent callback to a method on this twist.\n *\n * ExtraArgs are strongly typed to match the method's signature. They must be serializable.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass (type-checked, must be serializable)\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.callback(this.onWebhook, \"calendar\", 123);\n * ```\n */\n protected callback<\n TArgs extends Serializable[],\n Fn extends (...args: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n // Overload when caller provides the first argument\n protected callback<\n TArgs extends Serializable[],\n Fn extends (arg1: any, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n protected async callback<\n TArgs extends Serializable[],\n Fn extends (...args: any[]) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Like callback(), but for an Action, which receives the action as the first argument.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass after the action\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.actionCallback(this.doSomething, 123);\n * const action: Action = {\n * type: ActionType.callback,\n * title: \"Do Something\",\n * callback,\n * };\n * ```\n */\n protected async actionCallback<\n TArgs extends Serializable[],\n Fn extends (action: Action, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Deletes a specific callback by its token.\n *\n * @param token - The callback token to delete\n * @returns Promise that resolves when the callback is deleted\n */\n protected async deleteCallback(token: Callback): Promise<void> {\n return this.tools.callbacks.delete(token);\n }\n\n /**\n * Deletes all callbacks for this twist.\n *\n * @returns Promise that resolves when all callbacks are deleted\n */\n protected async deleteAllCallbacks(): Promise<void> {\n return this.tools.callbacks.deleteAll();\n }\n\n /**\n * Executes a callback by its token inline in the current execution.\n *\n * **Use `this.runTask()` instead for batch continuations and long-running work.**\n * `this.run()` executes inline, sharing the current request count (~1000 limit)\n * and blocking the HTTP response. This causes timeouts when used in lifecycle\n * methods like `onChannelEnabled` or `syncBatch` continuations.\n *\n * `this.run()` is appropriate when you need the callback's **return value** —\n * e.g., running a parent callback token that returns data. For fire-and-forget\n * work, always prefer `this.runTask()`.\n *\n * @param token - The callback token to execute\n * @param args - Optional arguments to pass to the callback\n * @returns Promise resolving to the callback result\n */\n protected async run(token: Callback, ...args: []): Promise<any> {\n return this.tools.callbacks.run(token, ...args);\n }\n\n /**\n * Retrieves a value from persistent storage by key.\n *\n * Values are automatically deserialized using SuperJSON, which\n * properly restores Date objects, Maps, Sets, and other complex types.\n *\n * @template T - The expected type of the stored value (must be Serializable)\n * @param key - The storage key to retrieve\n * @returns Promise resolving to the stored value or null\n */\n protected async get<T extends import(\"./index\").Serializable>(\n key: string\n ): Promise<T | null> {\n return this.tools.store.get(key);\n }\n\n /**\n * Stores a value in persistent storage.\n *\n * The value will be serialized using SuperJSON and stored persistently.\n * SuperJSON automatically handles Date objects, Maps, Sets, undefined values,\n * and other complex types that standard JSON doesn't support.\n *\n * **Important**: Functions and Symbols cannot be stored.\n * **For function references**: Use callbacks instead of storing functions directly.\n *\n * @example\n * ```typescript\n * // ✅ Date objects are preserved\n * await this.set(\"sync_state\", {\n * lastSync: new Date(),\n * minDate: new Date(2024, 0, 1)\n * });\n *\n * // ✅ undefined is now supported\n * await this.set(\"data\", { name: \"test\", optional: undefined });\n *\n * // ❌ WRONG: Cannot store functions directly\n * await this.set(\"handler\", this.myHandler);\n *\n * // ✅ CORRECT: Create a callback token first\n * const token = await this.callback(this.myHandler, \"arg1\", \"arg2\");\n * await this.set(\"handler_token\", token);\n *\n * // Later, execute the callback\n * const token = await this.get<string>(\"handler_token\");\n * await this.run(token, args);\n * ```\n *\n * @template T - The type of value being stored (must be Serializable)\n * @param key - The storage key to use\n * @param value - The value to store (must be SuperJSON-serializable)\n * @returns Promise that resolves when the value is stored\n */\n protected async set<T extends import(\"./index\").Serializable>(\n key: string,\n value: T\n ): Promise<void> {\n return this.tools.store.set(key, value);\n }\n\n /**\n * Removes a specific key from persistent storage.\n *\n * @param key - The storage key to remove\n * @returns Promise that resolves when the key is removed\n */\n protected async clear(key: string): Promise<void> {\n return this.tools.store.clear(key);\n }\n\n /**\n * Removes all keys from this twist's storage.\n *\n * @returns Promise that resolves when all keys are removed\n */\n protected async clearAll(): Promise<void> {\n return this.tools.store.clearAll();\n }\n\n /**\n * Queues a callback to execute in a separate worker context.\n *\n * @param callback - The callback token created with `this.callback()`\n * @param options - Optional configuration for the execution\n * @param options.runAt - If provided, schedules execution at this time; otherwise runs immediately\n * @returns Promise resolving to a cancellation token (only for scheduled executions)\n */\n protected async runTask(\n callback: Callback,\n options?: { runAt?: Date }\n ): Promise<string | void> {\n return this.tools.tasks.runTask(callback, options);\n }\n\n /**\n * Cancels a previously scheduled execution.\n *\n * @param token - The cancellation token returned by runTask() with runAt option\n * @returns Promise that resolves when the cancellation is processed\n */\n protected async cancelTask(token: string): Promise<void> {\n return this.tools.tasks.cancelTask(token);\n }\n\n /**\n * Cancels all scheduled executions for this twist.\n *\n * @returns Promise that resolves when all cancellations are processed\n */\n protected async cancelAllTasks(): Promise<void> {\n return this.tools.tasks.cancelAllTasks();\n }\n\n /**\n * Called when the twist is installed by a user.\n *\n * This method should contain initialization logic such as seeding\n * initial threads, configuring webhooks, or establishing external\n * connections. When it runs, `this.userId` is already populated with\n * the installing user's ID.\n *\n * @param context - Optional context containing the actor who triggered activation\n * @returns Promise that resolves when activation is complete\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n activate(context?: { actor: Actor }): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a new version of the twist is deployed.\n *\n * This method should contain migration logic for updating old data structures\n * or setting up new resources that weren't needed by the previous version.\n * It is called once per active twist_instance with the new version.\n *\n * @returns Promise that resolves when upgrade is complete\n */\n upgrade(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist's options configuration changes.\n *\n * Override to react to option changes, e.g. archiving items when a sync\n * type is toggled off, or starting sync when a type is toggled on.\n *\n * @param oldOptions - The previously resolved options\n * @param newOptions - The newly resolved options\n * @returns Promise that resolves when the change is handled\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onOptionsChanged(\n oldOptions: Record<string, any>,\n newOptions: Record<string, any>\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist is removed from a priority.\n *\n * This method should contain cleanup logic such as removing webhooks,\n * cleaning up external resources, or performing final data operations.\n *\n * @returns Promise that resolves when deactivation is complete\n */\n deactivate(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a thread created by this twist is updated.\n * Override to implement two-way sync with an external system.\n *\n * @param thread - The updated thread\n * @param changes - Tag additions and removals on the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onThreadUpdated(\n thread: Thread,\n changes: {\n tagsAdded: Record<Tag, ActorId[]>;\n tagsRemoved: Record<Tag, ActorId[]>;\n }\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread created by this twist.\n * Override to implement two-way sync (e.g. syncing notes as comments).\n *\n * Notes created by the twist itself are filtered out to prevent loops.\n *\n * Returning a string sets the note's `key` for future upsert matching,\n * linking the Plot note to its external counterpart so that subsequent\n * syncs (reactions, edits) update the existing note instead of creating duplicates.\n *\n * @param note - The newly created note\n * @returns Optional note key for external deduplication\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onNoteCreated(note: Note, ...args: any[]): Promise<string | void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link is created in a connected source channel.\n * Requires `link: true` in Plot options.\n *\n * @param link - The newly created link\n * @param notes - Notes on the link's thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkCreated(link: Link, notes: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link in a connected source channel is updated.\n * Requires `link: true` in Plot options.\n *\n * @param link - The updated link\n * @param notes - Notes on the link's thread (optional)\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkUpdated(link: Link, notes?: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread with a link from a connected channel.\n * Requires `link: true` in Plot options.\n *\n * @param note - The newly created note\n * @param link - The link associated with the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkNoteCreated(note: Note, link: Link): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Waits for tool initialization to complete.\n * Called automatically by the entrypoint before lifecycle methods.\n * @internal\n */\n async waitForReady(): Promise<void> {\n await this.toolShed.waitForReady();\n }\n}\n";
7
+ export default "import { type Action, type Actor, type ActorId, type Link, type Note, type Thread, Uuid } from \"./plot\";\nimport type { Tag } from \"./tag\";\nimport { type ITool } from \"./tool\";\nimport type { Callback } from \"./tools/callbacks\";\nimport type { Serializable } from \"./utils/serializable\";\nimport type { InferTools, ToolBuilder, ToolShed } from \"./utils/types\";\n\n/**\n * Base class for all twists.\n *\n * A twist is installed at the workspace level and is owned by a single user\n * (see `this.userId`). It has no inherent priority scope: threads, notes, and\n * links it creates are filed against the owner's priorities, with automatic\n * priority matching when no explicit target is provided.\n *\n * Override `build()` to declare tool dependencies and lifecycle methods to\n * handle events.\n *\n * @example\n * ```typescript\n * class FlatteringTwist extends Twist<FlatteringTwist> {\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * };\n * }\n *\n * async activate() {\n * await this.tools.plot.createThread({\n * title: \"Hello, good looking!\",\n * });\n * }\n * }\n * ```\n */\nexport abstract class Twist<TSelf> {\n /**\n * When `true`, users may install multiple instances of this twist within\n * the same scope (personal workspace or team). Each instance must have a\n * distinct name.\n *\n * Defaults to `false` (single instance per scope).\n *\n * @example\n * ```typescript\n * class WorkflowTwist extends Twist<WorkflowTwist> {\n * static readonly multipleInstances = true;\n * // ...\n * }\n * ```\n */\n static readonly multipleInstances?: boolean;\n\n /**\n * The user ID (`twist_instance.owner_id`) that installed this twist.\n * Populated by the runtime before any lifecycle method runs.\n */\n protected userId!: Uuid;\n\n constructor(protected id: Uuid, private toolShed: ToolShed) {}\n\n /**\n * Gets the initialized tools for this twist.\n * @throws Error if called before initialization is complete\n */\n protected get tools(): InferTools<TSelf> {\n return this.toolShed.getTools<InferTools<TSelf>>();\n }\n\n /**\n * Declares tool dependencies for this twist.\n * Return an object mapping tool names to build() promises.\n *\n * @param build - The build function to use for declaring dependencies\n * @returns Object mapping tool names to tool promises\n *\n * @example\n * ```typescript\n * build(build: ToolBuilder) {\n * return {\n * plot: build(Plot),\n * calendar: build(GoogleCalendar, { apiKey: \"...\" }),\n * };\n * }\n * ```\n */\n abstract build(build: ToolBuilder): Record<string, Promise<ITool>>;\n\n /**\n * Creates a persistent callback to a method on this twist.\n *\n * ExtraArgs are strongly typed to match the method's signature. They must be serializable.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass (type-checked, must be serializable)\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.callback(this.onWebhook, \"calendar\", 123);\n * ```\n */\n protected callback<\n TArgs extends Serializable[],\n Fn extends (...args: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n // Overload when caller provides the first argument\n protected callback<\n TArgs extends Serializable[],\n Fn extends (arg1: any, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback>;\n protected async callback<\n TArgs extends Serializable[],\n Fn extends (...args: any[]) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Like callback(), but for an Action, which receives the action as the first argument.\n *\n * @param fn - The method to callback\n * @param extraArgs - Additional arguments to pass after the action\n * @returns Promise resolving to a persistent callback token\n *\n * @example\n * ```typescript\n * const callback = await this.actionCallback(this.doSomething, 123);\n * const action: Action = {\n * type: ActionType.callback,\n * title: \"Do Something\",\n * callback,\n * };\n * ```\n */\n protected async actionCallback<\n TArgs extends Serializable[],\n Fn extends (action: Action, ...extraArgs: TArgs) => any\n >(fn: Fn, ...extraArgs: TArgs): Promise<Callback> {\n return this.tools.callbacks.create(fn, ...extraArgs);\n }\n\n /**\n * Deletes a specific callback by its token.\n *\n * @param token - The callback token to delete\n * @returns Promise that resolves when the callback is deleted\n */\n protected async deleteCallback(token: Callback): Promise<void> {\n return this.tools.callbacks.delete(token);\n }\n\n /**\n * Deletes all callbacks for this twist.\n *\n * @returns Promise that resolves when all callbacks are deleted\n */\n protected async deleteAllCallbacks(): Promise<void> {\n return this.tools.callbacks.deleteAll();\n }\n\n /**\n * Executes a callback by its token inline in the current execution.\n *\n * **Use `this.runTask()` instead for batch continuations and long-running work.**\n * `this.run()` executes inline, sharing the current request count (~1000 limit)\n * and blocking the HTTP response. This causes timeouts when used in lifecycle\n * methods like `onChannelEnabled` or `syncBatch` continuations.\n *\n * `this.run()` is appropriate when you need the callback's **return value** —\n * e.g., running a parent callback token that returns data. For fire-and-forget\n * work, always prefer `this.runTask()`.\n *\n * @param token - The callback token to execute\n * @param args - Optional arguments to pass to the callback\n * @returns Promise resolving to the callback result\n */\n protected async run(token: Callback, ...args: []): Promise<any> {\n return this.tools.callbacks.run(token, ...args);\n }\n\n /**\n * Retrieves a value from persistent storage by key.\n *\n * Values are automatically deserialized using SuperJSON, which\n * properly restores Date objects, Maps, Sets, and other complex types.\n *\n * @template T - The expected type of the stored value (must be Serializable)\n * @param key - The storage key to retrieve\n * @returns Promise resolving to the stored value or null\n */\n protected async get<T extends import(\"./index\").Serializable>(\n key: string\n ): Promise<T | null> {\n return this.tools.store.get(key);\n }\n\n /**\n * Stores a value in persistent storage.\n *\n * The value will be serialized using SuperJSON and stored persistently.\n * SuperJSON automatically handles Date objects, Maps, Sets, undefined values,\n * and other complex types that standard JSON doesn't support.\n *\n * **Important**: Functions and Symbols cannot be stored.\n * **For function references**: Use callbacks instead of storing functions directly.\n *\n * @example\n * ```typescript\n * // ✅ Date objects are preserved\n * await this.set(\"sync_state\", {\n * lastSync: new Date(),\n * minDate: new Date(2024, 0, 1)\n * });\n *\n * // ✅ undefined is now supported\n * await this.set(\"data\", { name: \"test\", optional: undefined });\n *\n * // ❌ WRONG: Cannot store functions directly\n * await this.set(\"handler\", this.myHandler);\n *\n * // ✅ CORRECT: Create a callback token first\n * const token = await this.callback(this.myHandler, \"arg1\", \"arg2\");\n * await this.set(\"handler_token\", token);\n *\n * // Later, execute the callback\n * const token = await this.get<string>(\"handler_token\");\n * await this.run(token, args);\n * ```\n *\n * @template T - The type of value being stored (must be Serializable)\n * @param key - The storage key to use\n * @param value - The value to store (must be SuperJSON-serializable)\n * @returns Promise that resolves when the value is stored\n */\n protected async set<T extends import(\"./index\").Serializable>(\n key: string,\n value: T\n ): Promise<void> {\n return this.tools.store.set(key, value);\n }\n\n /**\n * Removes a specific key from persistent storage.\n *\n * @param key - The storage key to remove\n * @returns Promise that resolves when the key is removed\n */\n protected async clear(key: string): Promise<void> {\n return this.tools.store.clear(key);\n }\n\n /**\n * Removes all keys from this twist's storage.\n *\n * @returns Promise that resolves when all keys are removed\n */\n protected async clearAll(): Promise<void> {\n return this.tools.store.clearAll();\n }\n\n /**\n * Queues a callback to execute in a separate worker context.\n *\n * @param callback - The callback token created with `this.callback()`\n * @param options - Optional configuration for the execution\n * @param options.runAt - If provided, schedules execution at this time; otherwise runs immediately\n * @returns Promise resolving to a cancellation token (only for scheduled executions)\n */\n protected async runTask(\n callback: Callback,\n options?: { runAt?: Date }\n ): Promise<string | void> {\n return this.tools.tasks.runTask(callback, options);\n }\n\n /**\n * Cancels a previously scheduled execution.\n *\n * @param token - The cancellation token returned by runTask() with runAt option\n * @returns Promise that resolves when the cancellation is processed\n */\n protected async cancelTask(token: string): Promise<void> {\n return this.tools.tasks.cancelTask(token);\n }\n\n /**\n * Cancels all scheduled executions for this twist.\n *\n * @returns Promise that resolves when all cancellations are processed\n */\n protected async cancelAllTasks(): Promise<void> {\n return this.tools.tasks.cancelAllTasks();\n }\n\n /**\n * Called when the twist is installed by a user.\n *\n * This method should contain initialization logic such as seeding\n * initial threads, configuring webhooks, or establishing external\n * connections. When it runs, `this.userId` is already populated with\n * the installing user's ID.\n *\n * @param context - Optional context containing the actor who triggered activation\n * @returns Promise that resolves when activation is complete\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n activate(context?: { actor: Actor }): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a new version of the twist is deployed.\n *\n * This method should contain migration logic for updating old data structures\n * or setting up new resources that weren't needed by the previous version.\n * It is called once per active twist_instance with the new version.\n *\n * @returns Promise that resolves when upgrade is complete\n */\n upgrade(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist's options configuration changes.\n *\n * Override to react to option changes, e.g. archiving items when a sync\n * type is toggled off, or starting sync when a type is toggled on.\n *\n * @param oldOptions - The previously resolved options\n * @param newOptions - The newly resolved options\n * @returns Promise that resolves when the change is handled\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onOptionsChanged(\n oldOptions: Record<string, any>,\n newOptions: Record<string, any>\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when the twist is uninstalled.\n *\n * This method should contain cleanup logic such as removing webhooks,\n * cleaning up external resources, or performing final data operations.\n *\n * @returns Promise that resolves when deactivation is complete\n */\n deactivate(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a thread created by this twist is updated.\n * Override to implement two-way sync with an external system.\n *\n * @param thread - The updated thread\n * @param changes - Tag additions and removals on the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onThreadUpdated(\n thread: Thread,\n changes: {\n tagsAdded: Record<Tag, ActorId[]>;\n tagsRemoved: Record<Tag, ActorId[]>;\n }\n ): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread created by this twist.\n * Override to implement two-way sync (e.g. syncing notes as comments).\n *\n * Notes created by the twist itself are filtered out to prevent loops.\n *\n * Returning a string sets the note's `key` for future upsert matching,\n * linking the Plot note to its external counterpart so that subsequent\n * syncs (reactions, edits) update the existing note instead of creating duplicates.\n *\n * @param note - The newly created note\n * @returns Optional note key for external deduplication\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onNoteCreated(note: Note, ...args: any[]): Promise<string | void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link is created in a connected source channel.\n * Requires `link: true` in Plot options.\n *\n * @param link - The newly created link\n * @param notes - Notes on the link's thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkCreated(link: Link, notes: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a link in a connected source channel is updated.\n * Requires `link: true` in Plot options.\n *\n * @param link - The updated link\n * @param notes - Notes on the link's thread (optional)\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkUpdated(link: Link, notes?: Note[]): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Called when a note is created on a thread with a link from a connected channel.\n * Requires `link: true` in Plot options.\n *\n * @param note - The newly created note\n * @param link - The link associated with the thread\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onLinkNoteCreated(note: Note, link: Link): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Waits for tool initialization to complete.\n * Called automatically by the entrypoint before lifecycle methods.\n * @internal\n */\n async waitForReady(): Promise<void> {\n await this.toolShed.waitForReady();\n }\n}\n";
8
8
  //# sourceMappingURL=twist.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"twist.js","sourceRoot":"","sources":["../../src/llm-docs/twist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAe,6/bAA6/b,CAAC"}
1
+ {"version":3,"file":"twist.js","sourceRoot":"","sources":["../../src/llm-docs/twist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAe,k9cAAk9c,CAAC"}
package/dist/twist.d.ts CHANGED
@@ -35,6 +35,22 @@ import type { InferTools, ToolBuilder, ToolShed } from "./utils/types";
35
35
  export declare abstract class Twist<TSelf> {
36
36
  protected id: Uuid;
37
37
  private toolShed;
38
+ /**
39
+ * When `true`, users may install multiple instances of this twist within
40
+ * the same scope (personal workspace or team). Each instance must have a
41
+ * distinct name.
42
+ *
43
+ * Defaults to `false` (single instance per scope).
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * class WorkflowTwist extends Twist<WorkflowTwist> {
48
+ * static readonly multipleInstances = true;
49
+ * // ...
50
+ * }
51
+ * ```
52
+ */
53
+ static readonly multipleInstances?: boolean;
38
54
  /**
39
55
  * The user ID (`twist_instance.owner_id`) that installed this twist.
40
56
  * Populated by the runtime before any lifecycle method runs.
@@ -251,7 +267,7 @@ export declare abstract class Twist<TSelf> {
251
267
  */
252
268
  onOptionsChanged(oldOptions: Record<string, any>, newOptions: Record<string, any>): Promise<void>;
253
269
  /**
254
- * Called when the twist is removed from a priority.
270
+ * Called when the twist is uninstalled.
255
271
  *
256
272
  * This method should contain cleanup logic such as removing webhooks,
257
273
  * cleaning up external resources, or performing final data operations.
@@ -1 +1 @@
1
- {"version":3,"file":"twist.d.ts","sourceRoot":"","sources":["../src/twist.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"twist.d.ts","sourceRoot":"","sources":["../src/twist.ts"],"names":[],"mappings":"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"}
package/dist/twist.js CHANGED
@@ -29,6 +29,22 @@
29
29
  export class Twist {
30
30
  id;
31
31
  toolShed;
32
+ /**
33
+ * When `true`, users may install multiple instances of this twist within
34
+ * the same scope (personal workspace or team). Each instance must have a
35
+ * distinct name.
36
+ *
37
+ * Defaults to `false` (single instance per scope).
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * class WorkflowTwist extends Twist<WorkflowTwist> {
42
+ * static readonly multipleInstances = true;
43
+ * // ...
44
+ * }
45
+ * ```
46
+ */
47
+ static multipleInstances;
32
48
  /**
33
49
  * The user ID (`twist_instance.owner_id`) that installed this twist.
34
50
  * Populated by the runtime before any lifecycle method runs.
@@ -245,7 +261,7 @@ export class Twist {
245
261
  return Promise.resolve();
246
262
  }
247
263
  /**
248
- * Called when the twist is removed from a priority.
264
+ * Called when the twist is uninstalled.
249
265
  *
250
266
  * This method should contain cleanup logic such as removing webhooks,
251
267
  * cleaning up external resources, or performing final data operations.
package/dist/twist.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"twist.js","sourceRoot":"","sources":["../src/twist.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"twist.js","sourceRoot":"","sources":["../src/twist.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plotday/twister",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "Plot Twist Creator - Build intelligent extensions that integrate and automate",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",