npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@super-productivity/plugin-api

v20.0.0

Published

TypeScript definitions for Super Productivity plugin development

Readme

@super-productivity/plugin-api

Official TypeScript definitions for developing Super Productivity plugins.

Versioned like the app: version X.Y.Z describes the plugin API of Super Productivity X.Y.Z. Your manifest's minSupVersion is the oldest app version your plugin installs on: set it to the oldest version that has every method you use, not simply the version you installed. (Versions before 19 were published separately and are outdated: if your package.json says ^1.0.1, change it.)

New to plugins? Start from the plugin starter and the plugin development guide. The complete API, with comments, is src/types.ts.

Installation

npm install --save-dev @super-productivity/plugin-api

Usage

Plain JavaScript (plugin.js)

The app provides a global PluginAPI. Reference the global types at the top of your file for autocomplete and, with // @ts-check, type checking:

// @ts-check
/// <reference types="@super-productivity/plugin-api/global" />

PluginAPI.registerHook(PluginAPI.Hooks.TASK_COMPLETE, (payload) => {
  console.log('Task completed!', payload.taskId);
});

Code inside a plugin's iframe (index.html) gets a filtered subset of the API; see "Iframe API Surface" in the guide.

TypeScript

Declare the global yourself, or instead put /// <reference types="@super-productivity/plugin-api/global" /> at the very top of the file and drop the declare const line:

import { PluginHooks } from '@super-productivity/plugin-api';
import type { PluginAPI as PluginAPIType } from '@super-productivity/plugin-api';

declare const PluginAPI: PluginAPIType;

PluginAPI.registerHook(PluginHooks.TASK_COMPLETE, (payload) => {
  PluginAPI.showSnack({
    msg: 'Task completed successfully!',
    type: 'SUCCESS',
    ico: 'celebration',
  });
});

// Register a header button
PluginAPI.registerHeaderButton({
  label: 'My Plugin',
  icon: 'extension',
  onClick: () => {
    PluginAPI.showIndexHtmlAsView();
  },
});

// Add an action to task and subtask context menus
PluginAPI.registerTaskContextMenuEntry({
  id: 'copy-external-link',
  label: 'Copy external link',
  icon: 'link', // Optional Material icon ligature name; custom SVGs are not supported
  showFor: ['TASK'], // Omit for both targets; [] is invalid
  onClick: ({ taskId }) => {
    console.log('Selected task:', taskId);
  },
});

// Register a keyboard shortcut
PluginAPI.registerShortcut({
  id: 'my_shortcut',
  label: 'My Custom Shortcut',
  onExec: () => {
    PluginAPI.showSnack({
      msg: 'Shortcut executed!',
      type: 'SUCCESS',
    });
  },
});

Plugin Manifest

{
  "name": "My Awesome Plugin",
  "id": "my-awesome-plugin",
  "manifestVersion": 1,
  "version": "1.0.0",
  "minSupVersion": "19.3.0",
  "author": "Your Name",
  "description": "An awesome plugin for Super Productivity",
  "hooks": ["taskComplete", "taskUpdate"],
  "permissions": ["showSnack", "getTasks", "addTask", "showIndexHtmlAsView"],
  "iFrame": true,
  "uiKit": true,
  "icon": "icon.svg"
}

Available Types

Core Types

  • PluginAPI - Main plugin API interface
  • PluginManifest - Plugin configuration
  • PluginHooks - Available hook types
  • PluginBaseCfg - Runtime configuration
  • PluginTaskContextMenuEntryCfg - Task context-menu action configuration
  • PluginTaskContextMenuContext - Context passed to a task action
  • PluginTaskContextMenuTarget - Supported task-menu targets

Data Types

  • TaskData - Task information
  • ProjectData - Project information
  • TagData - Tag information

UI Types

  • DialogCfg - Dialog configuration
  • DialogResult - Dialog return value
  • SnackCfg - Notification configuration
  • PluginMenuEntryCfg - Menu entry configuration
  • PluginShortcutCfg - Keyboard shortcut configuration

Plugin Development Guide

1. Available Hooks

See PluginHooks in src/types.ts for the full list and each hook's payload type.

PERSISTED_DATA_CHANGED fires on any persistent-data change to this plugin after the host has finished its initial boot load — including remote sync deliveries and bulk imports. Handler receives no payload; re-call loadSyncedData(key?) for any key your plugin tracks to get fresh data (scoped to the calling plugin). Contract: call loadSyncedData() on plugin init for the initial state; then use this hook for subsequent changes. There is no replay-on-register, no per-key discrimination in the event, and no guaranteed ordering across rapid changes. Handlers must be idempotent.

2. Permissions

List the permissions your plugin uses in manifest.json. The app checks only three of them: nodeExecution (a desktop consent prompt), http together with allowedHosts (gates PluginAPI.request only) and deleteProject (gates that call only). The others are shown in the plugin's details but not enforced. Plugins are not sandboxed, so no permission limits what plugin code can read or change; see Security Considerations.

Declare what the plugin sends off the device in dataSharing ([] if nothing); the app shows it to users. See Declaring what your plugin sends.

  • nodeExecution - Run Node.js scripts (desktop only, after the user allows it)
  • http - Send PluginAPI.request calls to the hosts listed in allowedHosts
  • showSnack - Show notifications
  • notify - System notifications
  • showIndexHtmlAsView - Display plugin UI
  • openDialog - Show dialogs
  • getTasks - Read tasks
  • getArchivedTasks - Read archived tasks
  • getCurrentContextTasks - Read current context tasks
  • getSelectedTask - Read the task selected in the task detail panel
  • getFocusedTask - Read the currently focused task row, if any
  • addTask - Create tasks
  • getAllProjects - Read projects
  • addProject - Create projects
  • deleteProject - Delete a project and everything it contains (irreversible)
  • getAllTags - Read tags
  • addTag - Create tags
  • persistDataSynced - Persist plugin data
  • getAppState - Read-only snapshot of application state

3. Plugin Structure

my-plugin/
├── manifest.json
├── plugin.js
├── index.html (optional, if iFrame: true)
└── icon.svg (optional)

4. Example Plugin

// plugin.js
console.log('My Plugin initializing...', PluginAPI);

// Register hook for task completion
PluginAPI.registerHook(PluginAPI.Hooks.TASK_COMPLETE, function (taskData) {
  console.log('Task completed!', taskData);

  PluginAPI.showSnack({
    msg: '🎉 Task completed!',
    type: 'SUCCESS',
    ico: 'celebration',
  });
});

// Register header button
PluginAPI.registerHeaderButton({
  label: 'My Plugin',
  icon: 'dashboard',
  onClick: function () {
    PluginAPI.showIndexHtmlAsView();
  },
});

// Read full app state
const state = await PluginAPI.getAppState();

License

MIT - See the main Super Productivity repository for details.

Contributing

Please contribute to the main Super Productivity repository.