@tickernelz/paperclip-pro-plugin-sdk 2026.925.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.
Files changed (72) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +1307 -0
  3. package/dist/.paperclip-build-complete +1 -0
  4. package/dist/bundlers.d.ts +57 -0
  5. package/dist/bundlers.d.ts.map +1 -0
  6. package/dist/bundlers.js +106 -0
  7. package/dist/bundlers.js.map +1 -0
  8. package/dist/define-plugin.d.ts +396 -0
  9. package/dist/define-plugin.d.ts.map +1 -0
  10. package/dist/define-plugin.js +87 -0
  11. package/dist/define-plugin.js.map +1 -0
  12. package/dist/dev-cli.d.ts +3 -0
  13. package/dist/dev-cli.d.ts.map +1 -0
  14. package/dist/dev-cli.js +49 -0
  15. package/dist/dev-cli.js.map +1 -0
  16. package/dist/dev-server.d.ts +34 -0
  17. package/dist/dev-server.d.ts.map +1 -0
  18. package/dist/dev-server.js +194 -0
  19. package/dist/dev-server.js.map +1 -0
  20. package/dist/host-client-factory.d.ts +326 -0
  21. package/dist/host-client-factory.d.ts.map +1 -0
  22. package/dist/host-client-factory.js +688 -0
  23. package/dist/host-client-factory.js.map +1 -0
  24. package/dist/index.d.ts +85 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +86 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/protocol.d.ts +2333 -0
  29. package/dist/protocol.d.ts.map +1 -0
  30. package/dist/protocol.duplex-channel.test.d.ts +2 -0
  31. package/dist/protocol.duplex-channel.test.d.ts.map +1 -0
  32. package/dist/protocol.duplex-channel.test.js +229 -0
  33. package/dist/protocol.duplex-channel.test.js.map +1 -0
  34. package/dist/protocol.js +364 -0
  35. package/dist/protocol.js.map +1 -0
  36. package/dist/testing.d.ts +203 -0
  37. package/dist/testing.d.ts.map +1 -0
  38. package/dist/testing.js +2475 -0
  39. package/dist/testing.js.map +1 -0
  40. package/dist/types.d.ts +1837 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +23 -0
  43. package/dist/types.js.map +1 -0
  44. package/dist/ui/clipboard.d.ts +8 -0
  45. package/dist/ui/clipboard.d.ts.map +1 -0
  46. package/dist/ui/clipboard.js +12 -0
  47. package/dist/ui/clipboard.js.map +1 -0
  48. package/dist/ui/components.d.ts +518 -0
  49. package/dist/ui/components.d.ts.map +1 -0
  50. package/dist/ui/components.js +135 -0
  51. package/dist/ui/components.js.map +1 -0
  52. package/dist/ui/hooks.d.ts +155 -0
  53. package/dist/ui/hooks.d.ts.map +1 -0
  54. package/dist/ui/hooks.js +195 -0
  55. package/dist/ui/hooks.js.map +1 -0
  56. package/dist/ui/index.d.ts +55 -0
  57. package/dist/ui/index.d.ts.map +1 -0
  58. package/dist/ui/index.js +52 -0
  59. package/dist/ui/index.js.map +1 -0
  60. package/dist/ui/runtime.d.ts +3 -0
  61. package/dist/ui/runtime.d.ts.map +1 -0
  62. package/dist/ui/runtime.js +30 -0
  63. package/dist/ui/runtime.js.map +1 -0
  64. package/dist/ui/types.d.ts +423 -0
  65. package/dist/ui/types.d.ts.map +1 -0
  66. package/dist/ui/types.js +17 -0
  67. package/dist/ui/types.js.map +1 -0
  68. package/dist/worker-rpc-host.d.ts +128 -0
  69. package/dist/worker-rpc-host.d.ts.map +1 -0
  70. package/dist/worker-rpc-host.js +1877 -0
  71. package/dist/worker-rpc-host.js.map +1 -0
  72. package/package.json +92 -0
@@ -0,0 +1 @@
1
+ {"sources":"a10c1d6ba303ebdf14ee2aa2a56fb59515084abb8cecd949308c605e7730d6b0","outputs":"63b53f567fb8d9ca7abd03addb239df711782929f06e7cae8ce60338389287b9"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Bundling presets for Paperclip plugins.
3
+ *
4
+ * These helpers return plain config objects so plugin authors can use them
5
+ * with esbuild or rollup without re-implementing host contract defaults.
6
+ */
7
+ export interface PluginBundlerPresetInput {
8
+ pluginRoot?: string;
9
+ manifestEntry?: string;
10
+ workerEntry?: string;
11
+ uiEntry?: string;
12
+ outdir?: string;
13
+ sourcemap?: boolean;
14
+ minify?: boolean;
15
+ }
16
+ export interface EsbuildLikeOptions {
17
+ entryPoints: string[];
18
+ outdir: string;
19
+ bundle: boolean;
20
+ format: "esm";
21
+ platform: "node" | "browser";
22
+ target: string;
23
+ sourcemap?: boolean;
24
+ minify?: boolean;
25
+ external?: string[];
26
+ }
27
+ export interface RollupLikeConfig {
28
+ input: string;
29
+ output: {
30
+ dir: string;
31
+ format: "es";
32
+ sourcemap?: boolean;
33
+ entryFileNames?: string;
34
+ };
35
+ external?: string[];
36
+ plugins?: unknown[];
37
+ }
38
+ export interface PluginBundlerPresets {
39
+ esbuild: {
40
+ worker: EsbuildLikeOptions;
41
+ ui?: EsbuildLikeOptions;
42
+ manifest: EsbuildLikeOptions;
43
+ };
44
+ rollup: {
45
+ worker: RollupLikeConfig;
46
+ ui?: RollupLikeConfig;
47
+ manifest: RollupLikeConfig;
48
+ };
49
+ }
50
+ /**
51
+ * Build esbuild/rollup baseline configs for plugin worker, manifest, and UI bundles.
52
+ *
53
+ * The presets intentionally externalize host/runtime deps (`react`, SDK packages)
54
+ * to match the Paperclip plugin loader contract.
55
+ */
56
+ export declare function createPluginBundlerPresets(input?: PluginBundlerPresetInput): PluginBundlerPresets;
57
+ //# sourceMappingURL=bundlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundlers.d.ts","sourceRoot":"","sources":["../src/bundlers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,IAAI,CAAC;QACb,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE;QACP,MAAM,EAAE,kBAAkB,CAAC;QAC3B,EAAE,CAAC,EAAE,kBAAkB,CAAC;QACxB,QAAQ,EAAE,kBAAkB,CAAC;KAC9B,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,gBAAgB,CAAC;QACzB,EAAE,CAAC,EAAE,gBAAgB,CAAC;QACtB,QAAQ,EAAE,gBAAgB,CAAC;KAC5B,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,GAAE,wBAA6B,GAAG,oBAAoB,CAoGrG"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Bundling presets for Paperclip plugins.
3
+ *
4
+ * These helpers return plain config objects so plugin authors can use them
5
+ * with esbuild or rollup without re-implementing host contract defaults.
6
+ */
7
+ /**
8
+ * Build esbuild/rollup baseline configs for plugin worker, manifest, and UI bundles.
9
+ *
10
+ * The presets intentionally externalize host/runtime deps (`react`, SDK packages)
11
+ * to match the Paperclip plugin loader contract.
12
+ */
13
+ export function createPluginBundlerPresets(input = {}) {
14
+ const uiExternal = [
15
+ "@tickernelz/paperclip-pro-plugin-sdk/ui",
16
+ "@tickernelz/paperclip-pro-plugin-sdk/ui/hooks",
17
+ "react",
18
+ "react-dom",
19
+ "react/jsx-runtime",
20
+ ];
21
+ const outdir = input.outdir ?? "dist";
22
+ const workerEntry = input.workerEntry ?? "src/worker.ts";
23
+ const manifestEntry = input.manifestEntry ?? "src/manifest.ts";
24
+ const uiEntry = input.uiEntry;
25
+ const sourcemap = input.sourcemap ?? true;
26
+ const minify = input.minify ?? false;
27
+ const esbuildWorker = {
28
+ entryPoints: [workerEntry],
29
+ outdir,
30
+ bundle: true,
31
+ format: "esm",
32
+ platform: "node",
33
+ target: "node24",
34
+ sourcemap,
35
+ minify,
36
+ external: ["react", "react-dom"],
37
+ };
38
+ const esbuildManifest = {
39
+ entryPoints: [manifestEntry],
40
+ outdir,
41
+ bundle: true,
42
+ format: "esm",
43
+ platform: "node",
44
+ target: "node24",
45
+ sourcemap,
46
+ external: ["@tickernelz/paperclip-pro-plugin-sdk"],
47
+ };
48
+ const esbuildUi = uiEntry
49
+ ? {
50
+ entryPoints: [uiEntry],
51
+ outdir: `${outdir}/ui`,
52
+ bundle: true,
53
+ format: "esm",
54
+ platform: "browser",
55
+ target: "es2022",
56
+ sourcemap,
57
+ minify,
58
+ external: uiExternal,
59
+ }
60
+ : undefined;
61
+ const rollupWorker = {
62
+ input: workerEntry,
63
+ output: {
64
+ dir: outdir,
65
+ format: "es",
66
+ sourcemap,
67
+ entryFileNames: "worker.js",
68
+ },
69
+ external: ["react", "react-dom"],
70
+ };
71
+ const rollupManifest = {
72
+ input: manifestEntry,
73
+ output: {
74
+ dir: outdir,
75
+ format: "es",
76
+ sourcemap,
77
+ entryFileNames: "manifest.js",
78
+ },
79
+ external: ["@tickernelz/paperclip-pro-plugin-sdk"],
80
+ };
81
+ const rollupUi = uiEntry
82
+ ? {
83
+ input: uiEntry,
84
+ output: {
85
+ dir: `${outdir}/ui`,
86
+ format: "es",
87
+ sourcemap,
88
+ entryFileNames: "index.js",
89
+ },
90
+ external: uiExternal,
91
+ }
92
+ : undefined;
93
+ return {
94
+ esbuild: {
95
+ worker: esbuildWorker,
96
+ manifest: esbuildManifest,
97
+ ...(esbuildUi ? { ui: esbuildUi } : {}),
98
+ },
99
+ rollup: {
100
+ worker: rollupWorker,
101
+ manifest: rollupManifest,
102
+ ...(rollupUi ? { ui: rollupUi } : {}),
103
+ },
104
+ };
105
+ }
106
+ //# sourceMappingURL=bundlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundlers.js","sourceRoot":"","sources":["../src/bundlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,396 @@
1
+ /**
2
+ * `definePlugin` — the top-level helper for authoring a Paperclip plugin.
3
+ *
4
+ * Plugin authors call `definePlugin()` and export the result as the default
5
+ * export from their worker entrypoint. The host imports the worker module,
6
+ * calls `setup()` with a `PluginContext`, and from that point the plugin
7
+ * responds to events, jobs, webhooks, and UI requests through the context.
8
+ *
9
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // dist/worker.ts
14
+ * import { definePlugin } from "@tickernelz/paperclip-pro-plugin-sdk";
15
+ *
16
+ * export default definePlugin({
17
+ * async setup(ctx) {
18
+ * ctx.logger.info("Linear sync plugin starting");
19
+ *
20
+ * // Subscribe to events
21
+ * ctx.events.on("issue.created", async (event) => {
22
+ * const companyId = event.companyId;
23
+ * const config = await ctx.config.get(companyId);
24
+ * const apiKey = await ctx.secrets.resolve(config.apiKeyRef, { companyId, configPath: "apiKeyRef" });
25
+ * await ctx.http.fetch(`https://api.linear.app/...`, {
26
+ * method: "POST",
27
+ * headers: { Authorization: `Bearer ${apiKey}` },
28
+ * body: JSON.stringify({ title: event.payload.title }),
29
+ * });
30
+ * });
31
+ *
32
+ * // Register a job handler
33
+ * ctx.jobs.register("full-sync", async (job) => {
34
+ * ctx.logger.info("Running full-sync job", { runId: job.runId });
35
+ * // ... sync logic
36
+ * });
37
+ *
38
+ * // Register data for the UI
39
+ * ctx.data.register("sync-health", async ({ companyId }) => {
40
+ * const state = await ctx.state.get({
41
+ * scopeKind: "company",
42
+ * scopeId: String(companyId),
43
+ * stateKey: "last-sync",
44
+ * });
45
+ * return { lastSync: state };
46
+ * });
47
+ * },
48
+ * });
49
+ * ```
50
+ */
51
+ import type { PluginContext } from "./types.js";
52
+ import type { PluginEnvironmentAcquireLeaseParams, PluginEnvironmentDestroyLeaseParams, PluginEnvironmentExecuteParams, PluginEnvironmentExecuteResult, PluginEnvironmentRunnerIngressEndpointParams, PluginEnvironmentRunnerIngressEndpoint, PluginEnvironmentSyncInParams, PluginEnvironmentSyncOutParams, PluginEnvironmentSyncResult, PluginEnvironmentStartInteractiveSetupParams, PluginEnvironmentInteractiveSetupSession, PluginEnvironmentGetInteractiveSetupParams, PluginEnvironmentCaptureTemplateParams, PluginEnvironmentCaptureTemplateResult, PluginEnvironmentCancelInteractiveSetupParams, PluginEnvironmentCancelInteractiveSetupResult, PluginEnvironmentDeleteTemplateParams, PluginEnvironmentDeleteTemplateResult, PluginEnvironmentLease, PluginEnvironmentProbeParams, PluginEnvironmentProbeResult, PluginEnvironmentRealizeWorkspaceParams, PluginEnvironmentRealizeWorkspaceResult, PluginEnvironmentReleaseLeaseParams, PluginEnvironmentTerminationReceipt, PluginEnvironmentResumeLeaseParams, PluginEnvironmentValidateConfigParams, PluginEnvironmentValidationResult, DetectExternalObjectsParams, DetectExternalObjectsResult, ResolveExternalObjectParams, PluginExternalObjectResolveResult, RefreshExternalObjectsParams, RefreshExternalObjectsResult, PluginLoginPtyOpenParams, PluginLoginPtyOpenResult, PluginLoginPtyInputParams, PluginLoginPtyStopParams, PluginLoginPtyCloseParams, PluginLoginPtyCloseResult, PluginDuplexChannelOpenParams, PluginDuplexChannelOpenResult, PluginDuplexChannelWriteParams, PluginDuplexChannelStopParams, PluginDuplexChannelCloseParams, PluginDuplexChannelCloseResult } from "./protocol.js";
53
+ /**
54
+ * Optional plugin-reported diagnostics returned from the `health()` RPC method.
55
+ *
56
+ * @see PLUGIN_SPEC.md §13.2 — `health`
57
+ */
58
+ export interface PluginHealthDiagnostics {
59
+ /** Machine-readable status: `"ok"` | `"degraded"` | `"error"`. */
60
+ status: "ok" | "degraded" | "error";
61
+ /** Human-readable description of the current health state. */
62
+ message?: string;
63
+ /** Plugin-reported key-value diagnostics (e.g. connection status, queue depth). */
64
+ details?: Record<string, unknown>;
65
+ }
66
+ /**
67
+ * Result returned from the `validateConfig()` RPC method.
68
+ *
69
+ * @see PLUGIN_SPEC.md §13.3 — `validateConfig`
70
+ */
71
+ export interface PluginConfigValidationResult {
72
+ /** Whether the config is valid. */
73
+ ok: boolean;
74
+ /** Non-fatal warnings about the config. */
75
+ warnings?: string[];
76
+ /** Validation errors (populated when `ok` is `false`). */
77
+ errors?: string[];
78
+ }
79
+ /**
80
+ * Input received by the plugin worker's `handleWebhook` handler.
81
+ *
82
+ * @see PLUGIN_SPEC.md §13.7 — `handleWebhook`
83
+ */
84
+ export interface PluginWebhookInput {
85
+ /** Endpoint key matching the manifest declaration. */
86
+ endpointKey: string;
87
+ /** Inbound request headers. */
88
+ headers: Record<string, string | string[]>;
89
+ /** Raw request body as a UTF-8 string. */
90
+ rawBody: string;
91
+ /** Parsed JSON body (if applicable and parseable). */
92
+ parsedBody?: unknown;
93
+ /** Unique request identifier for idempotency checks. */
94
+ requestId: string;
95
+ }
96
+ export interface PluginApiRequestInput {
97
+ routeKey: string;
98
+ method: string;
99
+ path: string;
100
+ params: Record<string, string>;
101
+ query: Record<string, string | string[]>;
102
+ body: unknown;
103
+ actor: {
104
+ actorType: "user" | "agent";
105
+ actorId: string;
106
+ agentId?: string | null;
107
+ userId?: string | null;
108
+ runId?: string | null;
109
+ };
110
+ companyId: string;
111
+ headers: Record<string, string>;
112
+ }
113
+ export interface PluginApiResponse {
114
+ status?: number;
115
+ headers?: Record<string, string>;
116
+ body?: unknown;
117
+ }
118
+ /**
119
+ * Scope metadata delivered alongside a `configChanged` RPC so the worker knows
120
+ * *which company's* configuration changed.
121
+ *
122
+ * The host→worker `configChanged` message has always carried the company scope,
123
+ * but the SDK historically dropped it before invoking `onConfigChanged`, leaving
124
+ * proactive plugins to keep a single worker-global config. That is safe for a
125
+ * single-tenant plugin but silently collapses a multi-company plugin onto
126
+ * whichever company's config was delivered last. Threading the scope through
127
+ * lets a `multiCompanyConfig` plugin maintain per-company state.
128
+ *
129
+ * @see PLUGIN_SPEC.md §13.4 — `configChanged`
130
+ */
131
+ export interface PluginConfigChangeContext {
132
+ /**
133
+ * The company whose configuration changed, or `null` for an instance/global
134
+ * save that is not bound to a specific company.
135
+ */
136
+ companyId: string | null;
137
+ }
138
+ /**
139
+ * The plugin definition shape passed to `definePlugin()`.
140
+ *
141
+ * The only required field is `setup`, which receives the `PluginContext` and
142
+ * is where the plugin registers its handlers (events, jobs, data, actions,
143
+ * tools, etc.).
144
+ *
145
+ * All other lifecycle hooks are optional. If a hook is not implemented the
146
+ * host applies default behaviour (e.g. restarting the worker on config change
147
+ * instead of calling `onConfigChanged`).
148
+ *
149
+ * @see PLUGIN_SPEC.md §13 — Host-Worker Protocol
150
+ */
151
+ export interface PluginDefinition {
152
+ /**
153
+ * Called once when the plugin worker starts up, after `initialize` completes.
154
+ *
155
+ * This is where the plugin registers all its handlers: event subscriptions,
156
+ * job handlers, data/action handlers, and tool registrations. Registration
157
+ * must be synchronous after `setup` resolves — do not register handlers
158
+ * inside async callbacks that may resolve after `setup` returns.
159
+ *
160
+ * @param ctx - The full plugin context provided by the host
161
+ */
162
+ setup(ctx: PluginContext): Promise<void>;
163
+ /**
164
+ * Called when the host wants to know if the plugin is healthy.
165
+ *
166
+ * The host polls this on a regular interval and surfaces the result in the
167
+ * plugin health dashboard. If not implemented, the host infers health from
168
+ * worker process liveness.
169
+ *
170
+ * @see PLUGIN_SPEC.md §13.2 — `health`
171
+ */
172
+ onHealth?(): Promise<PluginHealthDiagnostics>;
173
+ /**
174
+ * When true, this plugin's worker correctly serves configuration from more
175
+ * than one company inside a single worker process — for example by keying its
176
+ * state on `context.companyId` in `onConfigChanged` and running one connection
177
+ * / subscription set per company.
178
+ *
179
+ * When false or omitted (the default), the plugin is treated as single-tenant.
180
+ * The host then **fails closed** if `configChanged` would ever deliver a
181
+ * second, distinct company's configuration to the same worker: instead of
182
+ * silently collapsing the worker onto whichever company arrived last (a
183
+ * cross-tenant identity/secret confusion bug), the delivery is rejected with
184
+ * `PLUGIN_RPC_ERROR_CODES.CROSS_TENANT_CONFIG`. Re-delivering an unchanged
185
+ * config for a different company (idempotent replay) is still allowed.
186
+ */
187
+ multiCompanyConfig?: boolean;
188
+ /**
189
+ * Called when the operator updates this plugin's company-scoped configuration
190
+ * at runtime, without restarting the worker.
191
+ *
192
+ * If not implemented, the host restarts the worker to apply the new config.
193
+ *
194
+ * @param newConfig - The newly resolved configuration
195
+ * @param context - Scope of the change. `context.companyId` identifies the
196
+ * company whose config changed (null for an instance/global save). A
197
+ * multi-company plugin (`multiCompanyConfig: true`) MUST key its per-company
198
+ * state on this value rather than assuming a single global config.
199
+ * @see PLUGIN_SPEC.md §13.4 — `configChanged`
200
+ */
201
+ onConfigChanged?(newConfig: Record<string, unknown>, context?: PluginConfigChangeContext): Promise<void>;
202
+ /**
203
+ * Called when the host is about to shut down the plugin worker.
204
+ *
205
+ * The worker has at most 10 seconds (configurable via plugin config) to
206
+ * finish in-flight work and resolve this promise. After the deadline the
207
+ * host sends SIGTERM, then SIGKILL.
208
+ *
209
+ * @see PLUGIN_SPEC.md §12.5 — Graceful Shutdown Policy
210
+ */
211
+ onShutdown?(): Promise<void>;
212
+ /**
213
+ * Called to validate the current plugin configuration.
214
+ *
215
+ * The host calls this:
216
+ * - after the plugin starts (to surface config errors immediately)
217
+ * - after the operator saves a new config (to validate before persisting)
218
+ * - via the "Test Connection" button in the settings UI
219
+ *
220
+ * @param config - The configuration to validate
221
+ * @see PLUGIN_SPEC.md §13.3 — `validateConfig`
222
+ */
223
+ onValidateConfig?(config: Record<string, unknown>): Promise<PluginConfigValidationResult>;
224
+ /**
225
+ * Called to handle an inbound webhook delivery.
226
+ *
227
+ * The host routes `POST /api/plugins/:pluginId/webhooks/:endpointKey` to
228
+ * this handler. The plugin is responsible for signature verification using
229
+ * a resolved secret ref.
230
+ *
231
+ * If not implemented but webhooks are declared in the manifest, the host
232
+ * returns HTTP 501 for webhook deliveries.
233
+ *
234
+ * @param input - Webhook delivery metadata and payload
235
+ * @see PLUGIN_SPEC.md §13.7 — `handleWebhook`
236
+ */
237
+ onWebhook?(input: PluginWebhookInput): Promise<void>;
238
+ /**
239
+ * Called for manifest-declared scoped JSON API routes under
240
+ * `/api/plugins/:pluginId/api/*` after the host has enforced auth, company
241
+ * access, capabilities, and checkout policy.
242
+ */
243
+ onApiRequest?(input: PluginApiRequestInput): Promise<PluginApiResponse>;
244
+ /**
245
+ * Called when Paperclip scans issue/comment/document content and asks this
246
+ * plugin whether any sanitized URL candidates belong to its external object
247
+ * providers. The host has already stripped URL userinfo, query strings, and
248
+ * fragments unless provider-safe identity components were explicitly hashed.
249
+ *
250
+ * Requires `external.objects.detect`.
251
+ */
252
+ onDetectExternalObjects?(params: DetectExternalObjectsParams): Promise<DetectExternalObjectsResult>;
253
+ /**
254
+ * Called when Paperclip needs the current normalized status for one external
255
+ * object owned by a manifest-declared provider.
256
+ *
257
+ * Requires `external.objects.read`.
258
+ */
259
+ onResolveExternalObject?(params: ResolveExternalObjectParams): Promise<PluginExternalObjectResolveResult>;
260
+ /**
261
+ * Optional batch resolver used by providers that can refresh many objects
262
+ * more efficiently than individual `onResolveExternalObject` calls.
263
+ *
264
+ * Requires `external.objects.refresh`.
265
+ */
266
+ onRefreshExternalObjects?(params: RefreshExternalObjectsParams): Promise<RefreshExternalObjectsResult>;
267
+ /**
268
+ * Called to validate provider-specific configuration for a plugin-hosted
269
+ * environment driver.
270
+ */
271
+ onEnvironmentValidateConfig?(params: PluginEnvironmentValidateConfigParams): Promise<PluginEnvironmentValidationResult>;
272
+ /** Called to test reachability or readiness of a plugin-hosted environment. */
273
+ onEnvironmentProbe?(params: PluginEnvironmentProbeParams): Promise<PluginEnvironmentProbeResult>;
274
+ /** Called before a run starts to acquire a provider lease. */
275
+ onEnvironmentAcquireLease?(params: PluginEnvironmentAcquireLeaseParams): Promise<PluginEnvironmentLease>;
276
+ /** Called to reconnect to a previously acquired provider lease. */
277
+ onEnvironmentResumeLease?(params: PluginEnvironmentResumeLeaseParams): Promise<PluginEnvironmentLease>;
278
+ /** Called when a run finishes and the provider lease can be released. */
279
+ onEnvironmentReleaseLease?(params: PluginEnvironmentReleaseLeaseParams): Promise<PluginEnvironmentTerminationReceipt | void>;
280
+ /** Called when the host needs to force-destroy provider state. */
281
+ onEnvironmentDestroyLease?(params: PluginEnvironmentDestroyLeaseParams): Promise<PluginEnvironmentTerminationReceipt | void>;
282
+ /** Called to materialize the run workspace inside the provider lease. */
283
+ onEnvironmentRealizeWorkspace?(params: PluginEnvironmentRealizeWorkspaceParams): Promise<PluginEnvironmentRealizeWorkspaceResult>;
284
+ /** Called to execute a command inside the provider lease. */
285
+ onEnvironmentExecute?(params: PluginEnvironmentExecuteParams): Promise<PluginEnvironmentExecuteResult>;
286
+ /** Return an authenticated private WebSocket ingress for runnerd. */
287
+ onEnvironmentRunnerIngressEndpoint?(params: PluginEnvironmentRunnerIngressEndpointParams): Promise<PluginEnvironmentRunnerIngressEndpoint>;
288
+ /**
289
+ * Optional, opt-in: called before execution to place host files/directories at
290
+ * target sandbox paths using a provider-native transport instead of the default
291
+ * base64-over-exec fallback. Defining this hook (together with
292
+ * `onEnvironmentSyncOut`) advertises `environmentSyncIn`; leaving it undefined
293
+ * keeps the byte-identical fallback. See `doc/plugins/SANDBOX_FILE_SYNC_HOOKS.md`.
294
+ */
295
+ onEnvironmentSyncIn?(params: PluginEnvironmentSyncInParams): Promise<PluginEnvironmentSyncResult>;
296
+ /**
297
+ * Optional, opt-in: called after execution to copy sandbox files/directories
298
+ * back to target host paths using a provider-native transport. Defining this
299
+ * hook (together with `onEnvironmentSyncIn`) advertises `environmentSyncOut`.
300
+ * See `doc/plugins/SANDBOX_FILE_SYNC_HOOKS.md`.
301
+ */
302
+ onEnvironmentSyncOut?(params: PluginEnvironmentSyncOutParams): Promise<PluginEnvironmentSyncResult>;
303
+ /** Called to start an interactive setup sandbox and return redacted connection metadata. */
304
+ onEnvironmentStartInteractiveSetup?(params: PluginEnvironmentStartInteractiveSetupParams): Promise<PluginEnvironmentInteractiveSetupSession>;
305
+ /** Called to read setup status and, when authorized, a one-time connection payload. */
306
+ onEnvironmentGetInteractiveSetup?(params: PluginEnvironmentGetInteractiveSetupParams): Promise<PluginEnvironmentInteractiveSetupSession>;
307
+ /** Called to capture a reusable provider template from a live setup sandbox. */
308
+ onEnvironmentCaptureTemplate?(params: PluginEnvironmentCaptureTemplateParams): Promise<PluginEnvironmentCaptureTemplateResult>;
309
+ /** Called to cancel and clean up a setup sandbox without promoting a template. */
310
+ onEnvironmentCancelInteractiveSetup?(params: PluginEnvironmentCancelInteractiveSetupParams): Promise<PluginEnvironmentCancelInteractiveSetupResult>;
311
+ /** Called for optional best-effort cleanup of a captured provider template. */
312
+ onEnvironmentDeleteTemplate?(params: PluginEnvironmentDeleteTemplateParams): Promise<PluginEnvironmentDeleteTemplateResult>;
313
+ /**
314
+ * Called to open one live Claude `setup-token` login pseudo-terminal.
315
+ * The worker registers the terminal under the host route identifier and returns a
316
+ * worker session identifier for the output notification binding only. The worker
317
+ * streams output and the exit through `ctx.loginPty`, never as a reply.
318
+ * Defining the four `onLoginPty*` hooks advertises the four methods.
319
+ */
320
+ onLoginPtyOpen?(params: PluginLoginPtyOpenParams): Promise<PluginLoginPtyOpenResult>;
321
+ /** Called to write delayed input to an open login pseudo-terminal, keyed by the worker session identifier. */
322
+ onLoginPtyInput?(params: PluginLoginPtyInputParams): Promise<void>;
323
+ /** Called to stop an open login pseudo-terminal child, keyed by the worker session identifier. */
324
+ onLoginPtyStop?(params: PluginLoginPtyStopParams): Promise<void>;
325
+ /**
326
+ * Called to close an open login pseudo-terminal by the host route identifier. The
327
+ * worker closes the exact terminal registered under that identifier and returns a
328
+ * close acknowledgement that carries the same identifier.
329
+ */
330
+ onLoginPtyClose?(params: PluginLoginPtyCloseParams): Promise<PluginLoginPtyCloseResult>;
331
+ /**
332
+ * Called to open one persistent duplex channel. The worker registers the
333
+ * channel under the host route identifier and returns a worker session
334
+ * identifier for the data notification binding only. The worker streams data
335
+ * and the exit through worker→host notifications, never as a reply. Defining
336
+ * the four `onDuplexChannel*` hooks advertises the four methods. The host reads
337
+ * the open verb to gate the `duplexCommandStream` capability.
338
+ *
339
+ * HTTP/2 is the preferred transport. `queue_v1` is the soft-deprecated fallback.
340
+ */
341
+ onDuplexChannelOpen?(params: PluginDuplexChannelOpenParams): Promise<PluginDuplexChannelOpenResult>;
342
+ /** Called to write raw input to an open duplex channel, keyed by the worker session identifier. */
343
+ onDuplexChannelWrite?(params: PluginDuplexChannelWriteParams): Promise<void>;
344
+ /** Called to stop an open duplex channel child, keyed by the worker session identifier. */
345
+ onDuplexChannelStop?(params: PluginDuplexChannelStopParams): Promise<void>;
346
+ /**
347
+ * Called to close an open duplex channel by the host route identifier. The
348
+ * worker closes the exact channel registered under that identifier and returns
349
+ * a close acknowledgement that carries the same identifier.
350
+ */
351
+ onDuplexChannelClose?(params: PluginDuplexChannelCloseParams): Promise<PluginDuplexChannelCloseResult>;
352
+ }
353
+ /**
354
+ * The sealed plugin object returned by `definePlugin()`.
355
+ *
356
+ * Plugin authors export this as the default export from their worker
357
+ * entrypoint. The host imports it and calls the lifecycle methods.
358
+ *
359
+ * @see PLUGIN_SPEC.md §14 — SDK Surface
360
+ */
361
+ export interface PaperclipPlugin {
362
+ /** The original plugin definition passed to `definePlugin()`. */
363
+ readonly definition: PluginDefinition;
364
+ }
365
+ /**
366
+ * Define a Paperclip plugin.
367
+ *
368
+ * Call this function in your worker entrypoint and export the result as the
369
+ * default export. The host will import the module and call lifecycle methods
370
+ * on the returned object.
371
+ *
372
+ * @param definition - Plugin lifecycle handlers
373
+ * @returns A sealed `PaperclipPlugin` object for the host to consume
374
+ *
375
+ * @example
376
+ * ```ts
377
+ * import { definePlugin } from "@tickernelz/paperclip-pro-plugin-sdk";
378
+ *
379
+ * export default definePlugin({
380
+ * async setup(ctx) {
381
+ * ctx.logger.info("Plugin started");
382
+ * ctx.events.on("issue.created", async (event) => {
383
+ * // handle event
384
+ * });
385
+ * },
386
+ *
387
+ * async onHealth() {
388
+ * return { status: "ok" };
389
+ * },
390
+ * });
391
+ * ```
392
+ *
393
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
394
+ */
395
+ export declare function definePlugin(definition: PluginDefinition): PaperclipPlugin;
396
+ //# sourceMappingURL=define-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-plugin.d.ts","sourceRoot":"","sources":["../src/define-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `definePlugin` — the top-level helper for authoring a Paperclip plugin.
3
+ *
4
+ * Plugin authors call `definePlugin()` and export the result as the default
5
+ * export from their worker entrypoint. The host imports the worker module,
6
+ * calls `setup()` with a `PluginContext`, and from that point the plugin
7
+ * responds to events, jobs, webhooks, and UI requests through the context.
8
+ *
9
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // dist/worker.ts
14
+ * import { definePlugin } from "@tickernelz/paperclip-pro-plugin-sdk";
15
+ *
16
+ * export default definePlugin({
17
+ * async setup(ctx) {
18
+ * ctx.logger.info("Linear sync plugin starting");
19
+ *
20
+ * // Subscribe to events
21
+ * ctx.events.on("issue.created", async (event) => {
22
+ * const companyId = event.companyId;
23
+ * const config = await ctx.config.get(companyId);
24
+ * const apiKey = await ctx.secrets.resolve(config.apiKeyRef, { companyId, configPath: "apiKeyRef" });
25
+ * await ctx.http.fetch(`https://api.linear.app/...`, {
26
+ * method: "POST",
27
+ * headers: { Authorization: `Bearer ${apiKey}` },
28
+ * body: JSON.stringify({ title: event.payload.title }),
29
+ * });
30
+ * });
31
+ *
32
+ * // Register a job handler
33
+ * ctx.jobs.register("full-sync", async (job) => {
34
+ * ctx.logger.info("Running full-sync job", { runId: job.runId });
35
+ * // ... sync logic
36
+ * });
37
+ *
38
+ * // Register data for the UI
39
+ * ctx.data.register("sync-health", async ({ companyId }) => {
40
+ * const state = await ctx.state.get({
41
+ * scopeKind: "company",
42
+ * scopeId: String(companyId),
43
+ * stateKey: "last-sync",
44
+ * });
45
+ * return { lastSync: state };
46
+ * });
47
+ * },
48
+ * });
49
+ * ```
50
+ */
51
+ // ---------------------------------------------------------------------------
52
+ // definePlugin — top-level factory
53
+ // ---------------------------------------------------------------------------
54
+ /**
55
+ * Define a Paperclip plugin.
56
+ *
57
+ * Call this function in your worker entrypoint and export the result as the
58
+ * default export. The host will import the module and call lifecycle methods
59
+ * on the returned object.
60
+ *
61
+ * @param definition - Plugin lifecycle handlers
62
+ * @returns A sealed `PaperclipPlugin` object for the host to consume
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { definePlugin } from "@tickernelz/paperclip-pro-plugin-sdk";
67
+ *
68
+ * export default definePlugin({
69
+ * async setup(ctx) {
70
+ * ctx.logger.info("Plugin started");
71
+ * ctx.events.on("issue.created", async (event) => {
72
+ * // handle event
73
+ * });
74
+ * },
75
+ *
76
+ * async onHealth() {
77
+ * return { status: "ok" };
78
+ * },
79
+ * });
80
+ * ```
81
+ *
82
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
83
+ */
84
+ export function definePlugin(definition) {
85
+ return Object.freeze({ definition });
86
+ }
87
+ //# sourceMappingURL=define-plugin.js.map