npm.io
0.66.0 • Published 2d agoCLI

@plotday/twister

Licence
MIT
Version
0.66.0
Deps
8
Size
5.8 MB
Vulns
0
Weekly
0

favicon

Twister, the Plot Twist Creator

The official package for building Plot Twists -
smart automations that connect, organize, and prioritize your work.

Full Documentation →

Quick Start

Choose your path:

  • No Code - Write natural language, deploy in minutes
  • TypeScript - Full control with code

No-Code Quick Start

Describe your twist and Plot will do the rest.

1. Create plot-twist.md:

# My Calendar Twist

I want a twist that:

- Syncs my Google Calendar events into Plot
- Creates tasks for upcoming meetings
- Sends reminders 10 minutes before meetings

2. Deploy:

npx @plotday/twister login
npx @plotday/twister deploy

That's it! Learn more →

Developer Quick Start

Build twists with TypeScript for maximum flexibility.

1. Create a new twist:

npx @plotday/twister create

2. Implement your twist:

import { type ToolBuilder, Twist } from "@plotday/twister";
import { Plot, ThreadAccess } from "@plotday/twister/tools/plot";

export default class MyTwist extends Twist<MyTwist> {
  build(build: ToolBuilder) {
    return {
      plot: build(Plot, {
        thread: { access: ThreadAccess.Create },
      }),
    };
  }

  async activate() {
    await this.tools.plot.createThread({
      title: "Welcome! Your twist is now active.",
      notes: [
        {
          content: "Your twist is ready to use. Check out the [documentation](https://twist.plot.day) to learn more.",
        },
      ],
    });
  }
}

3. Deploy:

npx plot login
npm run deploy

Complete guide →


Core Concepts

Twists

Twists are smart automations that connect, organize, and prioritize your work. They implement opinionated workflows and respond to lifecycle events. A twist is installed at the workspace level and owned by a single user.

// Lifecycle methods
async activate(context?)   // When the twist is installed
async deactivate()         // When the twist is uninstalled
async upgrade()            // When a new version is deployed
Twist Tools

Twist tools provide capabilities to twists. They are usually unopinionated and do nothing on their own.

Built-in Tools:

  • Plot - Manage threads, notes, and focuses
  • Store - Persistent key-value storage
  • AI - Language models with structured output
  • Integrations - OAuth authentication and channel lifecycle
  • Network - HTTP access and webhooks
  • Tasks - Background task execution
  • Callbacks - Persistent function references

View all tools →

External service integrations (Google Calendar, Slack, Linear, etc.) are built as Connectors — see Building Connectors.

Threads and Notes

A Thread represents something done or to be done (a task, event, or conversation). Notes represent updates and details on that thread.

Think of a Thread like a messaging thread and Notes as messages in that thread. Always create threads with an initial note, and add notes for updates rather than creating new threads.

Data sync: When syncing from external systems, connectors save Links (external items attached to threads) via integrations.saveLink(), using Link.sources for deduplication and Note.key for upsertable notes — no manual ID tracking needed. See the Sync Strategies guide for detailed patterns.

import { ActionType } from "@plotday/twister";

// Create a thread with an initial note
const threadId = await this.tools.plot.createThread({
  title: "Review pull request",
  notes: [
    {
      key: "description", // Use key for upsertable notes
      content: "New PR ready for review",
      actions: [
        {
          type: ActionType.external,
          title: "View PR",
          url: "https://github.com/org/repo/pull/123",
        },
      ],
    },
  ],
});

// Add or update a note using key (upserts if key exists)
await this.tools.plot.createNote({
  thread: { id: threadId },
  key: "approval", // Using key enables upserts
  content: "LGTM! Approved ✅",
});

Learn more →


CLI Commands

# Authentication
plot login

# Twist management
plot create                    # Create new twist project
plot generate                  # Generate code from plot-twist.md
plot lint                      # Check for build or lint errors
plot build                     # Bundle without deploying
plot deploy                    # Deploy to Plot
plot logs                      # Stream real-time twist logs

# Priority management
plot priority list             # List all priorities
plot priority create           # Create new priority

Complete CLI reference →


Documentation

Full Documentation at twist.plot.day

Guides
Reference

Examples

Simple Note Twist
export default class WelcomeTwist extends Twist<WelcomeTwist> {
  build(build: ToolBuilder) {
    return {
      plot: build(Plot, {
        thread: { access: ThreadAccess.Create },
      }),
    };
  }

  async activate() {
    await this.tools.plot.createThread({
      title: "Welcome to Plot! 👋",
      notes: [
        {
          content: "This twist will help you get started with Plot.",
        },
      ],
    });
  }
}
GitHub Connector
import { Connector, type ToolBuilder } from "@plotday/twister";
import {
  AuthProvider,
  type AuthToken,
  type Authorization,
  type Channel,
  Integrations,
} from "@plotday/twister/tools/integrations";

export default class GitHubConnector extends Connector<GitHubConnector> {
  readonly provider = AuthProvider.GitHub;
  readonly scopes = ["repo"];

  build(build: ToolBuilder) {
    return {
      integrations: build(Integrations),
    };
  }

  async getChannels(
    auth: Authorization | null,
    token: AuthToken | null
  ): Promise<Channel[]> {
    // Return repositories the user can sync
    const repos = await this.listRepos(token);
    return repos.map((repo) => ({
      id: repo.id,
      title: repo.full_name,
    }));
  }

  async onChannelEnabled(channel: Channel) {
    // Start syncing issues from this repository
  }

  async onChannelDisabled(channel: Channel) {
    // Stop syncing and clean up
  }
}

More examples →


TypeScript Configuration

Extend the Twist Creator's base configuration in your tsconfig.json:

{
  "extends": "@plotday/twister/tsconfig.base.json",
  "include": ["src/*.ts"]
}

Support


License

MIT Plot Technologies Inc.

Keywords