Files
paperclip/doc/plugins/PLUGIN_AUTHORING_GUIDE.md

4.0 KiB

Plugin Authoring Guide

This guide describes the current, implemented way to create a Paperclip plugin in this repo.

It is intentionally narrower than PLUGIN_SPEC.md. The spec includes future ideas; this guide only covers the alpha surface that exists now.

Current reality

  • Treat plugin workers and plugin UI as trusted code.
  • Plugin UI runs as same-origin JavaScript inside the main Paperclip app.
  • Worker-side host APIs are capability-gated.
  • Plugin UI is not sandboxed by manifest capabilities.
  • There is no host-provided shared React component kit for plugins yet.
  • ctx.assets is not supported in the current runtime.

Scaffold a plugin

Use the scaffold package:

pnpm --filter @paperclipai/create-paperclip-plugin build
node packages/plugins/create-paperclip-plugin/dist/index.js @yourscope/plugin-name --output ./packages/plugins/examples

For a plugin that lives outside the Paperclip repo:

pnpm --filter @paperclipai/create-paperclip-plugin build
node packages/plugins/create-paperclip-plugin/dist/index.js @yourscope/plugin-name \
  --output /absolute/path/to/plugin-repos \
  --sdk-path /absolute/path/to/paperclip/packages/plugins/sdk

That creates a package with:

  • src/manifest.ts
  • src/worker.ts
  • src/ui/index.tsx
  • tests/plugin.spec.ts
  • esbuild.config.mjs
  • rollup.config.mjs

Inside this monorepo, the scaffold uses workspace:* for @paperclipai/plugin-sdk.

Outside this monorepo, the scaffold snapshots @paperclipai/plugin-sdk from the local Paperclip checkout into a .paperclip-sdk/ tarball so you can build and test a plugin without publishing anything to npm first.

From the generated plugin folder:

pnpm install
pnpm typecheck
pnpm test
pnpm build

For local development, install it into Paperclip from an absolute local path through the plugin manager or API. The server supports local filesystem installs and watches local-path plugins for file changes so worker restarts happen automatically after rebuilds.

Example:

curl -X POST http://127.0.0.1:3100/api/plugins/install \
  -H "Content-Type: application/json" \
  -d '{"packageName":"/absolute/path/to/your-plugin","isLocalPath":true}'

Supported alpha surface

Worker:

  • config
  • events
  • jobs
  • launchers
  • http
  • secrets
  • activity
  • state
  • entities
  • projects and project workspaces
  • companies
  • issues and comments
  • agents and agent sessions
  • goals
  • data/actions
  • streams
  • tools
  • metrics
  • logger

UI:

  • usePluginData
  • usePluginAction
  • usePluginStream
  • usePluginToast
  • useHostContext
  • typed slot props from @paperclipai/plugin-sdk/ui

Mount surfaces currently wired in the host include:

  • page
  • settingsPage
  • dashboardWidget
  • sidebar
  • sidebarPanel
  • detailTab
  • taskDetailView
  • projectSidebarItem
  • globalToolbarButton
  • toolbarButton
  • contextMenuItem
  • commentAnnotation
  • commentContextMenuItem

Company routes

Plugins may declare a page slot with routePath to own a company route like:

/:companyPrefix/<routePath>

Rules:

  • routePath must be a single lowercase slug
  • it cannot collide with reserved host routes
  • it cannot duplicate another installed plugin page route

Publishing guidance

  • Use npm packages as the deployment artifact.
  • Treat repo-local example installs as a development workflow only.
  • Prefer keeping plugin UI self-contained inside the package.
  • Do not rely on host design-system components or undocumented app internals.
  • GitHub repository installs are not a first-class workflow today. For local development, use a checked-out local path. For production, publish to npm or a private npm-compatible registry.

Verification before handoff

At minimum:

pnpm --filter <your-plugin-package> typecheck
pnpm --filter <your-plugin-package> test
pnpm --filter <your-plugin-package> build

If you changed host integration too, also run:

pnpm -r typecheck
pnpm test:run
pnpm build