Creating Plot Twists
    Preparing search index...

    Type Alias NewActivity

    NewActivity: (
        | { type: Note; done?: never }
        | { type: Action; done?: Date | null }
        | { type: Event; done?: never }
    ) & Partial<
        Omit<
            ActivityFields,
            "author"
            | "assignee"
            | "priority"
            | "tags"
            | "mentions"
            | "id"
            | "source",
        >,
    > & ({ id: Uuid } | { source: string } | {}) & (
        | { priority: Pick<Priority, "id"> }
        | { pickPriority?: PickPriorityConfig }
    ) & {
        author?: NewActor;
        assignee?: NewActor | null;
        tags?: NewTags;
        unread?: boolean;
        archived?: boolean;
        preview?: string | null;
        occurrences?: NewActivityOccurrence[];
        addRecurrenceExdates?: Date[];
        removeRecurrenceExdates?: Date[];
    }

    Type for creating new activities.

    Requires only the activity type, with all other fields optional. The author will be automatically assigned by the Plot system based on the current execution context. The ID can be optionally provided by tools for tracking and update detection purposes.

    Important: Defaults for Actions

    When creating an Activity of type Action:

    • start omitted → Defaults to current time (now) → "Do Now"
    • assignee omitted → Defaults to twist owner → Assigned action

    To create unassigned backlog items (common for synced tasks), you MUST explicitly set BOTH:

    • start: null → "Do Someday" (unscheduled)
    • assignee: null → Unassigned

    Scheduling States:

    • "Do Now" (actionable today): Omit start or set to current time
    • "Do Later" (scheduled): Set start to a future Date
    • "Do Someday" (backlog): Set start: null

    Priority can be specified in three ways:

    1. Explicit priority: priority: { id: "..." } - Use specific priority (disables pickPriority)
    2. Pick priority config: pickPriority: { ... } - Auto-select based on similarity
    3. Neither: Defaults to pickPriority: { content: true } for automatic matching

    Type Declaration

    • { type: Note; done?: never }
    • { type: Action; done?: Date | null }
    • { type: Event; done?: never }
    • { id: Uuid }
      • id: Uuid

        Unique identifier for the activity, generated by Uuid.Generate(). Specifying an ID allows tools to track and upsert activities.

    • { source: string }
      • source: string

        Canonical URL for the item in an external system. For example, https://acme.atlassian.net/browse/PROJ-42 could represent a Jira issue. When set, it uniquely identifies the activity within a priority tree. This performs an upsert.

    • {}
    • { priority: Pick<Priority, "id"> }
      • priority: Pick<Priority, "id">

        Explicit priority (required when specified) - disables automatic priority matching

    • { pickPriority?: PickPriorityConfig }
      • OptionalpickPriority?: PickPriorityConfig

        Configuration for automatic priority selection based on similarity

    • Optionalauthor?: NewActor

      The person that created the item. By default, it will be the twist itself.

    • Optionalassignee?: NewActor | null

      The person that assigned to the item.

    • Optionaltags?: NewTags

      All tags to set on the new activity.

    • Optionalunread?: boolean

      Whether the activity should be marked as unread for users.

      • undefined/omitted (default): Activity is unread for users, except auto-marked as read for the author if they are the twist owner (user)
      • true: Activity is explicitly unread for ALL users (use sparingly)
      • false: Activity is marked as read for all users in the priority at creation time

      For the default behavior, omit this field entirely. Use false for initial sync to avoid marking historical items as unread.

    • Optionalarchived?: boolean

      Whether the activity is archived.

      • true: Archive the activity
      • false: Unarchive the activity
      • undefined (default): Preserve current archive state

      Best practice: Set to false during initial syncs to ensure activities are unarchived. Omit during incremental syncs to preserve user's choice.

    • Optionalpreview?: string | null

      Optional preview content for the activity. Can be Markdown formatted. The preview will be automatically generated from this content (truncated to 100 chars).

      • string: Use this content for preview generation
      • null: Explicitly disable preview (no preview will be shown)
      • undefined (default): Fall back to legacy behavior (generate from first note with content)

      This field is write-only and won't be returned when reading activities.

    • Optionaloccurrences?: NewActivityOccurrence[]

      Create or update specific occurrences of a recurring activity. Each entry specifies overrides for a specific occurrence.

      When occurrence matches the recurrence rule but only tags are specified, the occurrence is created with just tags in activity_tag.occurrence (no activity_exception).

      When any other field is specified, creates/updates an activity_exception row.

      // Create recurring event with per-occurrence RSVPs
      const meeting: NewActivity = {
      type: ActivityType.Event,
      recurrenceRule: "FREQ=WEEKLY;BYDAY=MO",
      start: new Date("2025-01-20T14:00:00Z"),
      duration: 1800000, // 30 minutes
      occurrences: [
      {
      occurrence: new Date("2025-01-27T14:00:00Z"),
      tags: { [Tag.Skip]: [{ email: "[email protected]" }] }
      },
      {
      occurrence: new Date("2025-02-03T14:00:00Z"),
      start: new Date("2025-02-03T15:00:00Z"), // Reschedule this one
      tags: { [Tag.Attend]: [{ email: "[email protected]" }] }
      }
      ]
      };
    • OptionaladdRecurrenceExdates?: Date[]

      Dates to add to the recurrence exclusion list. These are merged with existing exdates. Use this for incremental updates (e.g., cancelling a single occurrence) instead of replacing the full list.

    • OptionalremoveRecurrenceExdates?: Date[]

      Dates to remove from the recurrence exclusion list. Use this to "uncancel" a previously excluded occurrence.

    // "Do Now" - Assigned to twist owner, actionable immediately
    const urgentTask: NewActivity = {
    type: ActivityType.Action,
    title: "Review pull request"
    // start omitted → defaults to now
    // assignee omitted → defaults to twist owner
    };

    // "Do Someday" - UNASSIGNED backlog item (for synced tasks)
    const backlogTask: NewActivity = {
    type: ActivityType.Action,
    title: "Refactor user service",
    start: null, // Must explicitly set to null
    assignee: null // Must explicitly set to null
    };

    // "Do Later" - Scheduled for specific date
    const futureTask: NewActivity = {
    type: ActivityType.Action,
    title: "Prepare Q1 review",
    start: new Date("2025-03-15")
    };

    // Note (typically unscheduled)
    const note: NewActivity = {
    type: ActivityType.Note,
    title: "Meeting notes",
    content: "Discussed Q4 roadmap...",
    start: null // Notes typically don't have scheduled times
    };

    // Event (always has explicit start/end times)
    const event: NewActivity = {
    type: ActivityType.Event,
    title: "Team standup",
    start: new Date("2025-01-15T10:00:00"),
    end: new Date("2025-01-15T10:30:00")
    };