@paperclipai/plugin-sdk 2026.3.17-canary.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.
- package/LICENSE +21 -0
- package/README.md +888 -0
- package/dist/bundlers.d.ts +57 -0
- package/dist/bundlers.d.ts.map +1 -0
- package/dist/bundlers.js +105 -0
- package/dist/bundlers.js.map +1 -0
- package/dist/define-plugin.d.ts +218 -0
- package/dist/define-plugin.d.ts.map +1 -0
- package/dist/define-plugin.js +85 -0
- package/dist/define-plugin.js.map +1 -0
- package/dist/dev-cli.d.ts +3 -0
- package/dist/dev-cli.d.ts.map +1 -0
- package/dist/dev-cli.js +49 -0
- package/dist/dev-cli.js.map +1 -0
- package/dist/dev-server.d.ts +34 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/dev-server.js +194 -0
- package/dist/dev-server.js.map +1 -0
- package/dist/host-client-factory.d.ts +229 -0
- package/dist/host-client-factory.d.ts.map +1 -0
- package/dist/host-client-factory.js +353 -0
- package/dist/host-client-factory.js.map +1 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +881 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +297 -0
- package/dist/protocol.js.map +1 -0
- package/dist/testing.d.ts +63 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +700 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +982 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/components.d.ts +257 -0
- package/dist/ui/components.d.ts.map +1 -0
- package/dist/ui/components.js +97 -0
- package/dist/ui/components.js.map +1 -0
- package/dist/ui/hooks.d.ts +120 -0
- package/dist/ui/hooks.d.ts.map +1 -0
- package/dist/ui/hooks.js +148 -0
- package/dist/ui/hooks.js.map +1 -0
- package/dist/ui/index.d.ts +50 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +48 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/runtime.d.ts +3 -0
- package/dist/ui/runtime.d.ts.map +1 -0
- package/dist/ui/runtime.js +30 -0
- package/dist/ui/runtime.js.map +1 -0
- package/dist/ui/types.d.ts +308 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +17 -0
- package/dist/ui/types.js.map +1 -0
- package/dist/worker-rpc-host.d.ts +127 -0
- package/dist/worker-rpc-host.d.ts.map +1 -0
- package/dist/worker-rpc-host.js +941 -0
- package/dist/worker-rpc-host.js.map +1 -0
- package/package.json +88 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,982 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for the Paperclip plugin worker-side SDK.
|
|
3
|
+
*
|
|
4
|
+
* These types define the stable public API surface that plugin workers import
|
|
5
|
+
* from `@paperclipai/plugin-sdk`. The host provides a concrete implementation
|
|
6
|
+
* of `PluginContext` to the plugin at initialisation time.
|
|
7
|
+
*
|
|
8
|
+
* @see PLUGIN_SPEC.md §14 — SDK Surface
|
|
9
|
+
* @see PLUGIN_SPEC.md §29.2 — SDK Versioning
|
|
10
|
+
*/
|
|
11
|
+
import type { PaperclipPluginManifestV1, PluginStateScopeKind, PluginEventType, PluginToolDeclaration, PluginLauncherDeclaration, Company, Project, Issue, IssueComment, IssueDocument, IssueDocumentSummary, Agent, Goal } from "@paperclipai/shared";
|
|
12
|
+
export type { PaperclipPluginManifestV1, PluginJobDeclaration, PluginWebhookDeclaration, PluginToolDeclaration, PluginUiSlotDeclaration, PluginUiDeclaration, PluginLauncherActionDeclaration, PluginLauncherRenderDeclaration, PluginLauncherDeclaration, PluginMinimumHostVersion, PluginRecord, PluginConfig, JsonSchema, PluginStatus, PluginCategory, PluginCapability, PluginUiSlotType, PluginUiSlotEntityType, PluginLauncherPlacementZone, PluginLauncherAction, PluginLauncherBounds, PluginLauncherRenderEnvironment, PluginStateScopeKind, PluginJobStatus, PluginJobRunStatus, PluginJobRunTrigger, PluginWebhookDeliveryStatus, PluginEventType, PluginBridgeErrorCode, Company, Project, Issue, IssueComment, IssueDocument, IssueDocumentSummary, Agent, Goal, } from "@paperclipai/shared";
|
|
13
|
+
/**
|
|
14
|
+
* A scope key identifies the exact location where plugin state is stored.
|
|
15
|
+
* Scope is partitioned by `scopeKind` and optional `scopeId`.
|
|
16
|
+
*
|
|
17
|
+
* Examples:
|
|
18
|
+
* - `{ scopeKind: "instance" }` — single global value for the whole instance
|
|
19
|
+
* - `{ scopeKind: "project", scopeId: "proj-uuid" }` — per-project state
|
|
20
|
+
* - `{ scopeKind: "issue", scopeId: "iss-uuid" }` — per-issue state
|
|
21
|
+
*
|
|
22
|
+
* @see PLUGIN_SPEC.md §21.3 `plugin_state`
|
|
23
|
+
*/
|
|
24
|
+
export interface ScopeKey {
|
|
25
|
+
/** What kind of Paperclip object this state is scoped to. */
|
|
26
|
+
scopeKind: PluginStateScopeKind;
|
|
27
|
+
/** UUID or text identifier for the scoped object. Omit for `instance` scope. */
|
|
28
|
+
scopeId?: string;
|
|
29
|
+
/** Optional sub-namespace within the scope to avoid key collisions. Defaults to `"default"`. */
|
|
30
|
+
namespace?: string;
|
|
31
|
+
/** The state key within the namespace. */
|
|
32
|
+
stateKey: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Optional filter applied when subscribing to an event. The host evaluates
|
|
36
|
+
* the filter server-side so filtered-out events never cross the process boundary.
|
|
37
|
+
*
|
|
38
|
+
* All filter fields are optional. If omitted the plugin receives every event
|
|
39
|
+
* of the subscribed type.
|
|
40
|
+
*
|
|
41
|
+
* @see PLUGIN_SPEC.md §16.1 — Event Filtering
|
|
42
|
+
*/
|
|
43
|
+
export interface EventFilter {
|
|
44
|
+
/** Only receive events for this project. */
|
|
45
|
+
projectId?: string;
|
|
46
|
+
/** Only receive events for this company. */
|
|
47
|
+
companyId?: string;
|
|
48
|
+
/** Only receive events for this agent. */
|
|
49
|
+
agentId?: string;
|
|
50
|
+
/** Additional arbitrary filter fields. */
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Envelope wrapping every domain event delivered to a plugin worker.
|
|
55
|
+
*
|
|
56
|
+
* @see PLUGIN_SPEC.md §16 — Event System
|
|
57
|
+
*/
|
|
58
|
+
export interface PluginEvent<TPayload = unknown> {
|
|
59
|
+
/** Unique event identifier (UUID). */
|
|
60
|
+
eventId: string;
|
|
61
|
+
/** The event type (e.g. `"issue.created"`). */
|
|
62
|
+
eventType: PluginEventType | `plugin.${string}`;
|
|
63
|
+
/** ISO 8601 timestamp when the event occurred. */
|
|
64
|
+
occurredAt: string;
|
|
65
|
+
/** ID of the actor that caused the event, if applicable. */
|
|
66
|
+
actorId?: string;
|
|
67
|
+
/** Type of actor: `"user"`, `"agent"`, `"system"`, or `"plugin"`. */
|
|
68
|
+
actorType?: "user" | "agent" | "system" | "plugin";
|
|
69
|
+
/** Primary entity involved in the event. */
|
|
70
|
+
entityId?: string;
|
|
71
|
+
/** Type of the primary entity. */
|
|
72
|
+
entityType?: string;
|
|
73
|
+
/** UUID of the company this event belongs to. */
|
|
74
|
+
companyId: string;
|
|
75
|
+
/** Typed event payload. */
|
|
76
|
+
payload: TPayload;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Context passed to a plugin job handler when the host triggers a scheduled run.
|
|
80
|
+
*
|
|
81
|
+
* @see PLUGIN_SPEC.md §13.6 — `runJob`
|
|
82
|
+
*/
|
|
83
|
+
export interface PluginJobContext {
|
|
84
|
+
/** Stable job key matching the declaration in the manifest. */
|
|
85
|
+
jobKey: string;
|
|
86
|
+
/** UUID for this specific job run instance. */
|
|
87
|
+
runId: string;
|
|
88
|
+
/** What triggered this run. */
|
|
89
|
+
trigger: "schedule" | "manual" | "retry";
|
|
90
|
+
/** ISO 8601 timestamp when the run was scheduled to start. */
|
|
91
|
+
scheduledAt: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Run context passed to a plugin tool handler when an agent invokes the tool.
|
|
95
|
+
*
|
|
96
|
+
* @see PLUGIN_SPEC.md §13.10 — `executeTool`
|
|
97
|
+
*/
|
|
98
|
+
export interface ToolRunContext {
|
|
99
|
+
/** UUID of the agent invoking the tool. */
|
|
100
|
+
agentId: string;
|
|
101
|
+
/** UUID of the current agent run. */
|
|
102
|
+
runId: string;
|
|
103
|
+
/** UUID of the company the run belongs to. */
|
|
104
|
+
companyId: string;
|
|
105
|
+
/** UUID of the project the run belongs to. */
|
|
106
|
+
projectId: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Result returned from a plugin tool handler.
|
|
110
|
+
*
|
|
111
|
+
* @see PLUGIN_SPEC.md §13.10 — `executeTool`
|
|
112
|
+
*/
|
|
113
|
+
export interface ToolResult {
|
|
114
|
+
/** String content returned to the agent. Required for success responses. */
|
|
115
|
+
content?: string;
|
|
116
|
+
/** Structured data returned alongside or instead of string content. */
|
|
117
|
+
data?: unknown;
|
|
118
|
+
/** If present, indicates the tool call failed. */
|
|
119
|
+
error?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Input for creating or updating a plugin-owned entity.
|
|
123
|
+
*
|
|
124
|
+
* @see PLUGIN_SPEC.md §21.3 `plugin_entities`
|
|
125
|
+
*/
|
|
126
|
+
export interface PluginEntityUpsert {
|
|
127
|
+
/** Plugin-defined entity type (e.g. `"linear-issue"`, `"github-pr"`). */
|
|
128
|
+
entityType: string;
|
|
129
|
+
/** Scope where this entity lives. */
|
|
130
|
+
scopeKind: PluginStateScopeKind;
|
|
131
|
+
/** Optional scope ID. */
|
|
132
|
+
scopeId?: string;
|
|
133
|
+
/** External identifier in the remote system (e.g. Linear issue ID). */
|
|
134
|
+
externalId?: string;
|
|
135
|
+
/** Human-readable title for display in the Paperclip UI. */
|
|
136
|
+
title?: string;
|
|
137
|
+
/** Optional status string. */
|
|
138
|
+
status?: string;
|
|
139
|
+
/** Full entity data blob. Must be JSON-serializable. */
|
|
140
|
+
data: Record<string, unknown>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A plugin-owned entity record as returned by `ctx.entities.list()`.
|
|
144
|
+
*
|
|
145
|
+
* @see PLUGIN_SPEC.md §21.3 `plugin_entities`
|
|
146
|
+
*/
|
|
147
|
+
export interface PluginEntityRecord {
|
|
148
|
+
/** UUID primary key. */
|
|
149
|
+
id: string;
|
|
150
|
+
/** Plugin-defined entity type. */
|
|
151
|
+
entityType: string;
|
|
152
|
+
/** Scope kind. */
|
|
153
|
+
scopeKind: PluginStateScopeKind;
|
|
154
|
+
/** Scope ID, if any. */
|
|
155
|
+
scopeId: string | null;
|
|
156
|
+
/** External identifier, if any. */
|
|
157
|
+
externalId: string | null;
|
|
158
|
+
/** Human-readable title. */
|
|
159
|
+
title: string | null;
|
|
160
|
+
/** Status string. */
|
|
161
|
+
status: string | null;
|
|
162
|
+
/** Full entity data. */
|
|
163
|
+
data: Record<string, unknown>;
|
|
164
|
+
/** ISO 8601 creation timestamp. */
|
|
165
|
+
createdAt: string;
|
|
166
|
+
/** ISO 8601 last-updated timestamp. */
|
|
167
|
+
updatedAt: string;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Query parameters for `ctx.entities.list()`.
|
|
171
|
+
*/
|
|
172
|
+
export interface PluginEntityQuery {
|
|
173
|
+
/** Filter by entity type. */
|
|
174
|
+
entityType?: string;
|
|
175
|
+
/** Filter by scope kind. */
|
|
176
|
+
scopeKind?: PluginStateScopeKind;
|
|
177
|
+
/** Filter by scope ID. */
|
|
178
|
+
scopeId?: string;
|
|
179
|
+
/** Filter by external ID. */
|
|
180
|
+
externalId?: string;
|
|
181
|
+
/** Maximum number of results to return. */
|
|
182
|
+
limit?: number;
|
|
183
|
+
/** Number of results to skip (for pagination). */
|
|
184
|
+
offset?: number;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Workspace metadata provided by the host. Plugins use this to resolve local
|
|
188
|
+
* filesystem paths for file browsing, git, terminal, and process operations.
|
|
189
|
+
*
|
|
190
|
+
* @see PLUGIN_SPEC.md §7 — Project Workspaces
|
|
191
|
+
* @see PLUGIN_SPEC.md §20 — Local Tooling
|
|
192
|
+
*/
|
|
193
|
+
export interface PluginWorkspace {
|
|
194
|
+
/** UUID primary key. */
|
|
195
|
+
id: string;
|
|
196
|
+
/** UUID of the parent project. */
|
|
197
|
+
projectId: string;
|
|
198
|
+
/** Display name for this workspace. */
|
|
199
|
+
name: string;
|
|
200
|
+
/** Absolute filesystem path to the workspace directory. */
|
|
201
|
+
path: string;
|
|
202
|
+
/** Whether this is the project's primary workspace. */
|
|
203
|
+
isPrimary: boolean;
|
|
204
|
+
/** ISO 8601 creation timestamp. */
|
|
205
|
+
createdAt: string;
|
|
206
|
+
/** ISO 8601 last-updated timestamp. */
|
|
207
|
+
updatedAt: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* `ctx.config` — read resolved operator configuration for this plugin.
|
|
211
|
+
*
|
|
212
|
+
* Plugin workers receive the resolved config at initialisation. Use `get()`
|
|
213
|
+
* to access the current configuration at any time. The host calls
|
|
214
|
+
* `configChanged` on the worker when the operator updates config at runtime.
|
|
215
|
+
*
|
|
216
|
+
* @see PLUGIN_SPEC.md §13.3 — `validateConfig`
|
|
217
|
+
* @see PLUGIN_SPEC.md §13.4 — `configChanged`
|
|
218
|
+
*/
|
|
219
|
+
export interface PluginConfigClient {
|
|
220
|
+
/**
|
|
221
|
+
* Returns the resolved operator configuration for this plugin instance.
|
|
222
|
+
* Values are validated against the plugin's `instanceConfigSchema` by the
|
|
223
|
+
* host before being passed to the worker.
|
|
224
|
+
*/
|
|
225
|
+
get(): Promise<Record<string, unknown>>;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* `ctx.events` — subscribe to and emit Paperclip domain events.
|
|
229
|
+
*
|
|
230
|
+
* Requires `events.subscribe` capability for `on()`.
|
|
231
|
+
* Requires `events.emit` capability for `emit()`.
|
|
232
|
+
*
|
|
233
|
+
* @see PLUGIN_SPEC.md §16 — Event System
|
|
234
|
+
*/
|
|
235
|
+
export interface PluginEventsClient {
|
|
236
|
+
/**
|
|
237
|
+
* Subscribe to a core Paperclip domain event or a plugin-namespaced event.
|
|
238
|
+
*
|
|
239
|
+
* @param name - Event type, e.g. `"issue.created"` or `"plugin.@acme/linear.sync-done"`
|
|
240
|
+
* @param fn - Async event handler
|
|
241
|
+
*/
|
|
242
|
+
on(name: PluginEventType | `plugin.${string}`, fn: (event: PluginEvent) => Promise<void>): () => void;
|
|
243
|
+
/**
|
|
244
|
+
* Subscribe to an event with an optional server-side filter.
|
|
245
|
+
*
|
|
246
|
+
* @param name - Event type
|
|
247
|
+
* @param filter - Server-side filter evaluated before dispatching to the worker
|
|
248
|
+
* @param fn - Async event handler
|
|
249
|
+
* @returns An unsubscribe function that removes the handler
|
|
250
|
+
*/
|
|
251
|
+
on(name: PluginEventType | `plugin.${string}`, filter: EventFilter, fn: (event: PluginEvent) => Promise<void>): () => void;
|
|
252
|
+
/**
|
|
253
|
+
* Emit a plugin-namespaced event. Other plugins with `events.subscribe` can
|
|
254
|
+
* subscribe to it using `"plugin.<pluginId>.<eventName>"`.
|
|
255
|
+
*
|
|
256
|
+
* Requires the `events.emit` capability.
|
|
257
|
+
*
|
|
258
|
+
* Plugin-emitted events are automatically namespaced: if the plugin ID is
|
|
259
|
+
* `"acme.linear"` and the event name is `"sync-done"`, the full event type
|
|
260
|
+
* becomes `"plugin.acme.linear.sync-done"`.
|
|
261
|
+
*
|
|
262
|
+
* @see PLUGIN_SPEC.md §16.2 — Plugin-to-Plugin Events
|
|
263
|
+
*
|
|
264
|
+
* @param name - Bare event name (e.g. `"sync-done"`)
|
|
265
|
+
* @param companyId - UUID of the company this event belongs to
|
|
266
|
+
* @param payload - JSON-serializable event payload
|
|
267
|
+
*/
|
|
268
|
+
emit(name: string, companyId: string, payload: unknown): Promise<void>;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* `ctx.jobs` — register handlers for scheduled jobs declared in the manifest.
|
|
272
|
+
*
|
|
273
|
+
* Requires `jobs.schedule` capability.
|
|
274
|
+
*
|
|
275
|
+
* @see PLUGIN_SPEC.md §17 — Scheduled Jobs
|
|
276
|
+
*/
|
|
277
|
+
export interface PluginJobsClient {
|
|
278
|
+
/**
|
|
279
|
+
* Register a handler for a scheduled job.
|
|
280
|
+
*
|
|
281
|
+
* The `key` must match a `jobKey` declared in the plugin manifest.
|
|
282
|
+
* The host calls this handler according to the job's declared `schedule`.
|
|
283
|
+
*
|
|
284
|
+
* @param key - Job key matching the manifest declaration
|
|
285
|
+
* @param fn - Async job handler
|
|
286
|
+
*/
|
|
287
|
+
register(key: string, fn: (job: PluginJobContext) => Promise<void>): void;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* A runtime launcher registration uses the same declaration shape as a
|
|
291
|
+
* manifest launcher entry.
|
|
292
|
+
*/
|
|
293
|
+
export type PluginLauncherRegistration = PluginLauncherDeclaration;
|
|
294
|
+
/**
|
|
295
|
+
* `ctx.launchers` — register launcher declarations at runtime.
|
|
296
|
+
*/
|
|
297
|
+
export interface PluginLaunchersClient {
|
|
298
|
+
/**
|
|
299
|
+
* Register launcher metadata for host discovery.
|
|
300
|
+
*
|
|
301
|
+
* If a launcher with the same id is registered more than once, the latest
|
|
302
|
+
* declaration replaces the previous one.
|
|
303
|
+
*/
|
|
304
|
+
register(launcher: PluginLauncherRegistration): void;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* `ctx.http` — make outbound HTTP requests.
|
|
308
|
+
*
|
|
309
|
+
* Requires `http.outbound` capability.
|
|
310
|
+
*
|
|
311
|
+
* @see PLUGIN_SPEC.md §15.1 — Capabilities: Runtime/Integration
|
|
312
|
+
*/
|
|
313
|
+
export interface PluginHttpClient {
|
|
314
|
+
/**
|
|
315
|
+
* Perform an outbound HTTP request.
|
|
316
|
+
*
|
|
317
|
+
* The host enforces `http.outbound` capability before allowing the call.
|
|
318
|
+
* Plugins may also use standard Node `fetch` or other libraries directly —
|
|
319
|
+
* this client exists for host-managed tracing and audit logging.
|
|
320
|
+
*
|
|
321
|
+
* @param url - Target URL
|
|
322
|
+
* @param init - Standard `RequestInit` options
|
|
323
|
+
* @returns The response
|
|
324
|
+
*/
|
|
325
|
+
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* `ctx.secrets` — resolve secret references.
|
|
329
|
+
*
|
|
330
|
+
* Requires `secrets.read-ref` capability.
|
|
331
|
+
*
|
|
332
|
+
* Plugins store secret *references* in their config (e.g. a secret name).
|
|
333
|
+
* This client resolves the reference through the Paperclip secret provider
|
|
334
|
+
* system and returns the resolved value at execution time.
|
|
335
|
+
*
|
|
336
|
+
* @see PLUGIN_SPEC.md §22 — Secrets
|
|
337
|
+
*/
|
|
338
|
+
export interface PluginSecretsClient {
|
|
339
|
+
/**
|
|
340
|
+
* Resolve a secret reference to its current value.
|
|
341
|
+
*
|
|
342
|
+
* The reference is a string identifier pointing to a secret configured
|
|
343
|
+
* in the Paperclip secret provider (e.g. `"MY_API_KEY"`).
|
|
344
|
+
*
|
|
345
|
+
* Secret values are resolved at call time and must never be cached or
|
|
346
|
+
* written to logs, config, or other persistent storage.
|
|
347
|
+
*
|
|
348
|
+
* @param secretRef - The secret reference string from plugin config
|
|
349
|
+
* @returns The resolved secret value
|
|
350
|
+
*/
|
|
351
|
+
resolve(secretRef: string): Promise<string>;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Input for writing a plugin activity log entry.
|
|
355
|
+
*
|
|
356
|
+
* @see PLUGIN_SPEC.md §21.4 — Activity Log Changes
|
|
357
|
+
*/
|
|
358
|
+
export interface PluginActivityLogEntry {
|
|
359
|
+
/** UUID of the company this activity belongs to. Required for auditing. */
|
|
360
|
+
companyId: string;
|
|
361
|
+
/** Human-readable description of the activity. */
|
|
362
|
+
message: string;
|
|
363
|
+
/** Optional entity type this activity relates to. */
|
|
364
|
+
entityType?: string;
|
|
365
|
+
/** Optional entity ID this activity relates to. */
|
|
366
|
+
entityId?: string;
|
|
367
|
+
/** Optional additional metadata. */
|
|
368
|
+
metadata?: Record<string, unknown>;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* `ctx.activity` — write plugin-originated activity log entries.
|
|
372
|
+
*
|
|
373
|
+
* Requires `activity.log.write` capability.
|
|
374
|
+
*
|
|
375
|
+
* @see PLUGIN_SPEC.md §21.4 — Activity Log Changes
|
|
376
|
+
*/
|
|
377
|
+
export interface PluginActivityClient {
|
|
378
|
+
/**
|
|
379
|
+
* Write an activity log entry attributed to this plugin.
|
|
380
|
+
*
|
|
381
|
+
* The host writes the entry with `actor_type = plugin` and
|
|
382
|
+
* `actor_id = <pluginId>`.
|
|
383
|
+
*
|
|
384
|
+
* @param entry - The activity log entry to write
|
|
385
|
+
*/
|
|
386
|
+
log(entry: PluginActivityLogEntry): Promise<void>;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* `ctx.state` — read and write plugin-scoped key-value state.
|
|
390
|
+
*
|
|
391
|
+
* Each plugin gets an isolated namespace: state written by plugin A can never
|
|
392
|
+
* be read or overwritten by plugin B. Within a plugin, state is partitioned by
|
|
393
|
+
* a five-part composite key: `(pluginId, scopeKind, scopeId, namespace, stateKey)`.
|
|
394
|
+
*
|
|
395
|
+
* **Scope kinds**
|
|
396
|
+
*
|
|
397
|
+
* | `scopeKind` | `scopeId` | Typical use |
|
|
398
|
+
* |-------------|-----------|-------------|
|
|
399
|
+
* | `"instance"` | omit | Global flags, last full-sync timestamps |
|
|
400
|
+
* | `"company"` | company UUID | Per-company sync cursors |
|
|
401
|
+
* | `"project"` | project UUID | Per-project settings, branch tracking |
|
|
402
|
+
* | `"project_workspace"` | workspace UUID | Per-workspace state |
|
|
403
|
+
* | `"agent"` | agent UUID | Per-agent memory |
|
|
404
|
+
* | `"issue"` | issue UUID | Idempotency keys, linked external IDs |
|
|
405
|
+
* | `"goal"` | goal UUID | Per-goal progress |
|
|
406
|
+
* | `"run"` | run UUID | Per-run checkpoints |
|
|
407
|
+
*
|
|
408
|
+
* **Namespaces**
|
|
409
|
+
*
|
|
410
|
+
* The optional `namespace` field (default: `"default"`) lets you group related
|
|
411
|
+
* keys within a scope without risking collisions between different logical
|
|
412
|
+
* subsystems inside the same plugin.
|
|
413
|
+
*
|
|
414
|
+
* **Security**
|
|
415
|
+
*
|
|
416
|
+
* Never store resolved secret values. Store only secret references and resolve
|
|
417
|
+
* them at call time via `ctx.secrets.resolve()`.
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```ts
|
|
421
|
+
* // Instance-global flag
|
|
422
|
+
* await ctx.state.set({ scopeKind: "instance", stateKey: "schema-version" }, 2);
|
|
423
|
+
*
|
|
424
|
+
* // Idempotency key per issue
|
|
425
|
+
* const synced = await ctx.state.get({ scopeKind: "issue", scopeId: issueId, stateKey: "synced-to-linear" });
|
|
426
|
+
* if (!synced) {
|
|
427
|
+
* await syncToLinear(issueId);
|
|
428
|
+
* await ctx.state.set({ scopeKind: "issue", scopeId: issueId, stateKey: "synced-to-linear" }, true);
|
|
429
|
+
* }
|
|
430
|
+
*
|
|
431
|
+
* // Per-project, namespaced for two integrations
|
|
432
|
+
* await ctx.state.set({ scopeKind: "project", scopeId: projectId, namespace: "linear", stateKey: "cursor" }, cursor);
|
|
433
|
+
* await ctx.state.set({ scopeKind: "project", scopeId: projectId, namespace: "github", stateKey: "last-event" }, eventId);
|
|
434
|
+
* ```
|
|
435
|
+
*
|
|
436
|
+
* `plugin.state.read` capability required for `get()`.
|
|
437
|
+
* `plugin.state.write` capability required for `set()` and `delete()`.
|
|
438
|
+
*
|
|
439
|
+
* @see PLUGIN_SPEC.md §21.3 `plugin_state`
|
|
440
|
+
*/
|
|
441
|
+
export interface PluginStateClient {
|
|
442
|
+
/**
|
|
443
|
+
* Read a state value.
|
|
444
|
+
*
|
|
445
|
+
* Returns the stored JSON value as-is, or `null` if no entry has been set
|
|
446
|
+
* for this scope+key combination. Falsy values (`false`, `0`, `""`) are
|
|
447
|
+
* returned correctly and are not confused with "not set".
|
|
448
|
+
*
|
|
449
|
+
* @param input - Scope key identifying the entry to read
|
|
450
|
+
* @returns The stored JSON value, or `null` if no value has been set
|
|
451
|
+
*/
|
|
452
|
+
get(input: ScopeKey): Promise<unknown>;
|
|
453
|
+
/**
|
|
454
|
+
* Write a state value. Creates the row if it does not exist; replaces it
|
|
455
|
+
* atomically (upsert) if it does. Safe to call concurrently.
|
|
456
|
+
*
|
|
457
|
+
* Any JSON-serializable value is accepted: objects, arrays, strings,
|
|
458
|
+
* numbers, booleans, and `null`.
|
|
459
|
+
*
|
|
460
|
+
* @param input - Scope key identifying the entry to write
|
|
461
|
+
* @param value - JSON-serializable value to store
|
|
462
|
+
*/
|
|
463
|
+
set(input: ScopeKey, value: unknown): Promise<void>;
|
|
464
|
+
/**
|
|
465
|
+
* Delete a state value. No-ops silently if the entry does not exist
|
|
466
|
+
* (idempotent by design — safe to call without prior `get()`).
|
|
467
|
+
*
|
|
468
|
+
* @param input - Scope key identifying the entry to delete
|
|
469
|
+
*/
|
|
470
|
+
delete(input: ScopeKey): Promise<void>;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* `ctx.entities` — create and query plugin-owned entity records.
|
|
474
|
+
*
|
|
475
|
+
* @see PLUGIN_SPEC.md §21.3 `plugin_entities`
|
|
476
|
+
*/
|
|
477
|
+
export interface PluginEntitiesClient {
|
|
478
|
+
/**
|
|
479
|
+
* Create or update a plugin entity record (upsert by `externalId` within
|
|
480
|
+
* the given scope, or by `id` if provided).
|
|
481
|
+
*
|
|
482
|
+
* @param input - Entity data to upsert
|
|
483
|
+
*/
|
|
484
|
+
upsert(input: PluginEntityUpsert): Promise<PluginEntityRecord>;
|
|
485
|
+
/**
|
|
486
|
+
* Query plugin entity records.
|
|
487
|
+
*
|
|
488
|
+
* @param query - Filter criteria
|
|
489
|
+
* @returns Matching entity records
|
|
490
|
+
*/
|
|
491
|
+
list(query: PluginEntityQuery): Promise<PluginEntityRecord[]>;
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* `ctx.projects` — read project and workspace metadata.
|
|
495
|
+
*
|
|
496
|
+
* Requires `projects.read` capability.
|
|
497
|
+
* Requires `project.workspaces.read` capability for workspace operations.
|
|
498
|
+
*
|
|
499
|
+
* @see PLUGIN_SPEC.md §7 — Project Workspaces
|
|
500
|
+
*/
|
|
501
|
+
export interface PluginProjectsClient {
|
|
502
|
+
/**
|
|
503
|
+
* List projects visible to the plugin.
|
|
504
|
+
*
|
|
505
|
+
* Requires the `projects.read` capability.
|
|
506
|
+
*/
|
|
507
|
+
list(input: {
|
|
508
|
+
companyId: string;
|
|
509
|
+
limit?: number;
|
|
510
|
+
offset?: number;
|
|
511
|
+
}): Promise<Project[]>;
|
|
512
|
+
/**
|
|
513
|
+
* Get a single project by ID.
|
|
514
|
+
*
|
|
515
|
+
* Requires the `projects.read` capability.
|
|
516
|
+
*/
|
|
517
|
+
get(projectId: string, companyId: string): Promise<Project | null>;
|
|
518
|
+
/**
|
|
519
|
+
* List all workspaces attached to a project.
|
|
520
|
+
*
|
|
521
|
+
* @param projectId - UUID of the project
|
|
522
|
+
* @param companyId - UUID of the company that owns the project
|
|
523
|
+
* @returns All workspaces for the project, ordered with primary first
|
|
524
|
+
*/
|
|
525
|
+
listWorkspaces(projectId: string, companyId: string): Promise<PluginWorkspace[]>;
|
|
526
|
+
/**
|
|
527
|
+
* Get the primary workspace for a project.
|
|
528
|
+
*
|
|
529
|
+
* @param projectId - UUID of the project
|
|
530
|
+
* @param companyId - UUID of the company that owns the project
|
|
531
|
+
* @returns The primary workspace, or `null` if no workspace is configured
|
|
532
|
+
*/
|
|
533
|
+
getPrimaryWorkspace(projectId: string, companyId: string): Promise<PluginWorkspace | null>;
|
|
534
|
+
/**
|
|
535
|
+
* Resolve the primary workspace for an issue by looking up the issue's
|
|
536
|
+
* project and returning its primary workspace.
|
|
537
|
+
*
|
|
538
|
+
* This is a convenience method that combines `issues.get()` and
|
|
539
|
+
* `getPrimaryWorkspace()` in a single RPC call.
|
|
540
|
+
*
|
|
541
|
+
* @param issueId - UUID of the issue
|
|
542
|
+
* @param companyId - UUID of the company that owns the issue
|
|
543
|
+
* @returns The primary workspace for the issue's project, or `null` if
|
|
544
|
+
* the issue has no project or the project has no workspace
|
|
545
|
+
*
|
|
546
|
+
* @see PLUGIN_SPEC.md §20 — Local Tooling
|
|
547
|
+
*/
|
|
548
|
+
getWorkspaceForIssue(issueId: string, companyId: string): Promise<PluginWorkspace | null>;
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* `ctx.data` — register `getData` handlers that back `usePluginData()` in the
|
|
552
|
+
* plugin's frontend components.
|
|
553
|
+
*
|
|
554
|
+
* The plugin's UI calls `usePluginData(key, params)` which routes through the
|
|
555
|
+
* host bridge to the worker's registered handler.
|
|
556
|
+
*
|
|
557
|
+
* @see PLUGIN_SPEC.md §13.8 — `getData`
|
|
558
|
+
*/
|
|
559
|
+
export interface PluginDataClient {
|
|
560
|
+
/**
|
|
561
|
+
* Register a handler for a plugin-defined data key.
|
|
562
|
+
*
|
|
563
|
+
* @param key - Stable string identifier for this data type (e.g. `"sync-health"`)
|
|
564
|
+
* @param handler - Async function that receives request params and returns JSON-serializable data
|
|
565
|
+
*/
|
|
566
|
+
register(key: string, handler: (params: Record<string, unknown>) => Promise<unknown>): void;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* `ctx.actions` — register `performAction` handlers that back
|
|
570
|
+
* `usePluginAction()` in the plugin's frontend components.
|
|
571
|
+
*
|
|
572
|
+
* @see PLUGIN_SPEC.md §13.9 — `performAction`
|
|
573
|
+
*/
|
|
574
|
+
export interface PluginActionsClient {
|
|
575
|
+
/**
|
|
576
|
+
* Register a handler for a plugin-defined action key.
|
|
577
|
+
*
|
|
578
|
+
* @param key - Stable string identifier for this action (e.g. `"resync"`)
|
|
579
|
+
* @param handler - Async function that receives action params and returns a result
|
|
580
|
+
*/
|
|
581
|
+
register(key: string, handler: (params: Record<string, unknown>) => Promise<unknown>): void;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* `ctx.tools` — register handlers for agent tools declared in the manifest.
|
|
585
|
+
*
|
|
586
|
+
* Requires `agent.tools.register` capability.
|
|
587
|
+
*
|
|
588
|
+
* Tool names are automatically namespaced by plugin ID at runtime.
|
|
589
|
+
*
|
|
590
|
+
* @see PLUGIN_SPEC.md §11 — Agent Tools
|
|
591
|
+
*/
|
|
592
|
+
export interface PluginToolsClient {
|
|
593
|
+
/**
|
|
594
|
+
* Register a handler for a plugin-contributed agent tool.
|
|
595
|
+
*
|
|
596
|
+
* @param name - Tool name matching the manifest declaration (without namespace prefix)
|
|
597
|
+
* @param declaration - Tool metadata (displayName, description, parametersSchema)
|
|
598
|
+
* @param fn - Async handler that executes the tool
|
|
599
|
+
*/
|
|
600
|
+
register(name: string, declaration: Pick<PluginToolDeclaration, "displayName" | "description" | "parametersSchema">, fn: (params: unknown, runCtx: ToolRunContext) => Promise<ToolResult>): void;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* `ctx.logger` — structured logging from the plugin worker.
|
|
604
|
+
*
|
|
605
|
+
* Log output is captured by the host, stored, and surfaced in the plugin
|
|
606
|
+
* health dashboard.
|
|
607
|
+
*
|
|
608
|
+
* @see PLUGIN_SPEC.md §26.1 — Logging
|
|
609
|
+
*/
|
|
610
|
+
export interface PluginLogger {
|
|
611
|
+
/** Log an informational message. */
|
|
612
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
613
|
+
/** Log a warning. */
|
|
614
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
615
|
+
/** Log an error. */
|
|
616
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
617
|
+
/** Log a debug message (may be suppressed in production). */
|
|
618
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* `ctx.metrics` — write plugin-contributed metrics.
|
|
622
|
+
*
|
|
623
|
+
* Requires `metrics.write` capability.
|
|
624
|
+
*
|
|
625
|
+
* @see PLUGIN_SPEC.md §15.1 — Capabilities: Data Write
|
|
626
|
+
*/
|
|
627
|
+
export interface PluginMetricsClient {
|
|
628
|
+
/**
|
|
629
|
+
* Write a numeric metric data point.
|
|
630
|
+
*
|
|
631
|
+
* @param name - Metric name (plugin-namespaced by the host)
|
|
632
|
+
* @param value - Numeric value
|
|
633
|
+
* @param tags - Optional key-value tags for filtering
|
|
634
|
+
*/
|
|
635
|
+
write(name: string, value: number, tags?: Record<string, string>): Promise<void>;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* `ctx.companies` — read company metadata.
|
|
639
|
+
*
|
|
640
|
+
* Requires `companies.read` capability.
|
|
641
|
+
*/
|
|
642
|
+
export interface PluginCompaniesClient {
|
|
643
|
+
/**
|
|
644
|
+
* List companies visible to this plugin.
|
|
645
|
+
*/
|
|
646
|
+
list(input?: {
|
|
647
|
+
limit?: number;
|
|
648
|
+
offset?: number;
|
|
649
|
+
}): Promise<Company[]>;
|
|
650
|
+
/**
|
|
651
|
+
* Get one company by ID.
|
|
652
|
+
*/
|
|
653
|
+
get(companyId: string): Promise<Company | null>;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* `ctx.issues.documents` — read and write issue documents.
|
|
657
|
+
*
|
|
658
|
+
* Requires:
|
|
659
|
+
* - `issue.documents.read` for `list` and `get`
|
|
660
|
+
* - `issue.documents.write` for `upsert` and `delete`
|
|
661
|
+
*
|
|
662
|
+
* @see PLUGIN_SPEC.md §14 — SDK Surface
|
|
663
|
+
*/
|
|
664
|
+
export interface PluginIssueDocumentsClient {
|
|
665
|
+
/**
|
|
666
|
+
* List all documents attached to an issue.
|
|
667
|
+
*
|
|
668
|
+
* Returns summary metadata (id, key, title, format, timestamps) without
|
|
669
|
+
* the full document body. Use `get()` to fetch a specific document's body.
|
|
670
|
+
*
|
|
671
|
+
* Requires the `issue.documents.read` capability.
|
|
672
|
+
*/
|
|
673
|
+
list(issueId: string, companyId: string): Promise<IssueDocumentSummary[]>;
|
|
674
|
+
/**
|
|
675
|
+
* Get a single document by key, including its full body content.
|
|
676
|
+
*
|
|
677
|
+
* Returns `null` if no document exists with the given key.
|
|
678
|
+
*
|
|
679
|
+
* Requires the `issue.documents.read` capability.
|
|
680
|
+
*
|
|
681
|
+
* @param issueId - UUID of the issue
|
|
682
|
+
* @param key - Document key (e.g. `"plan"`, `"design-spec"`)
|
|
683
|
+
* @param companyId - UUID of the company
|
|
684
|
+
*/
|
|
685
|
+
get(issueId: string, key: string, companyId: string): Promise<IssueDocument | null>;
|
|
686
|
+
/**
|
|
687
|
+
* Create or update a document on an issue.
|
|
688
|
+
*
|
|
689
|
+
* If a document with the given key already exists, it is updated and a new
|
|
690
|
+
* revision is created. If it does not exist, it is created.
|
|
691
|
+
*
|
|
692
|
+
* Requires the `issue.documents.write` capability.
|
|
693
|
+
*
|
|
694
|
+
* @param input - Document data including issueId, key, body, and optional title/format/changeSummary
|
|
695
|
+
*/
|
|
696
|
+
upsert(input: {
|
|
697
|
+
issueId: string;
|
|
698
|
+
key: string;
|
|
699
|
+
body: string;
|
|
700
|
+
companyId: string;
|
|
701
|
+
title?: string;
|
|
702
|
+
format?: string;
|
|
703
|
+
changeSummary?: string;
|
|
704
|
+
}): Promise<IssueDocument>;
|
|
705
|
+
/**
|
|
706
|
+
* Delete a document and all its revisions.
|
|
707
|
+
*
|
|
708
|
+
* No-ops silently if the document does not exist (idempotent).
|
|
709
|
+
*
|
|
710
|
+
* Requires the `issue.documents.write` capability.
|
|
711
|
+
*
|
|
712
|
+
* @param issueId - UUID of the issue
|
|
713
|
+
* @param key - Document key to delete
|
|
714
|
+
* @param companyId - UUID of the company
|
|
715
|
+
*/
|
|
716
|
+
delete(issueId: string, key: string, companyId: string): Promise<void>;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* `ctx.issues` — read and mutate issues plus comments.
|
|
720
|
+
*
|
|
721
|
+
* Requires:
|
|
722
|
+
* - `issues.read` for read operations
|
|
723
|
+
* - `issues.create` for create
|
|
724
|
+
* - `issues.update` for update
|
|
725
|
+
* - `issue.comments.read` for `listComments`
|
|
726
|
+
* - `issue.comments.create` for `createComment`
|
|
727
|
+
* - `issue.documents.read` for `documents.list` and `documents.get`
|
|
728
|
+
* - `issue.documents.write` for `documents.upsert` and `documents.delete`
|
|
729
|
+
*/
|
|
730
|
+
export interface PluginIssuesClient {
|
|
731
|
+
list(input: {
|
|
732
|
+
companyId: string;
|
|
733
|
+
projectId?: string;
|
|
734
|
+
assigneeAgentId?: string;
|
|
735
|
+
status?: Issue["status"];
|
|
736
|
+
limit?: number;
|
|
737
|
+
offset?: number;
|
|
738
|
+
}): Promise<Issue[]>;
|
|
739
|
+
get(issueId: string, companyId: string): Promise<Issue | null>;
|
|
740
|
+
create(input: {
|
|
741
|
+
companyId: string;
|
|
742
|
+
projectId?: string;
|
|
743
|
+
goalId?: string;
|
|
744
|
+
parentId?: string;
|
|
745
|
+
title: string;
|
|
746
|
+
description?: string;
|
|
747
|
+
priority?: Issue["priority"];
|
|
748
|
+
assigneeAgentId?: string;
|
|
749
|
+
}): Promise<Issue>;
|
|
750
|
+
update(issueId: string, patch: Partial<Pick<Issue, "title" | "description" | "status" | "priority" | "assigneeAgentId">>, companyId: string): Promise<Issue>;
|
|
751
|
+
listComments(issueId: string, companyId: string): Promise<IssueComment[]>;
|
|
752
|
+
createComment(issueId: string, body: string, companyId: string): Promise<IssueComment>;
|
|
753
|
+
/** Read and write issue documents. Requires `issue.documents.read` / `issue.documents.write`. */
|
|
754
|
+
documents: PluginIssueDocumentsClient;
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* `ctx.agents` — read and manage agents.
|
|
758
|
+
*
|
|
759
|
+
* Requires `agents.read` for reads; `agents.pause` / `agents.resume` /
|
|
760
|
+
* `agents.invoke` for write operations.
|
|
761
|
+
*/
|
|
762
|
+
export interface PluginAgentsClient {
|
|
763
|
+
list(input: {
|
|
764
|
+
companyId: string;
|
|
765
|
+
status?: Agent["status"];
|
|
766
|
+
limit?: number;
|
|
767
|
+
offset?: number;
|
|
768
|
+
}): Promise<Agent[]>;
|
|
769
|
+
get(agentId: string, companyId: string): Promise<Agent | null>;
|
|
770
|
+
/** Pause an agent. Throws if agent is terminated or not found. Requires `agents.pause`. */
|
|
771
|
+
pause(agentId: string, companyId: string): Promise<Agent>;
|
|
772
|
+
/** Resume a paused agent (sets status to idle). Throws if terminated, pending_approval, or not found. Requires `agents.resume`. */
|
|
773
|
+
resume(agentId: string, companyId: string): Promise<Agent>;
|
|
774
|
+
/** Invoke (wake up) an agent with a prompt payload. Throws if paused, terminated, pending_approval, or not found. Requires `agents.invoke`. */
|
|
775
|
+
invoke(agentId: string, companyId: string, opts: {
|
|
776
|
+
prompt: string;
|
|
777
|
+
reason?: string;
|
|
778
|
+
}): Promise<{
|
|
779
|
+
runId: string;
|
|
780
|
+
}>;
|
|
781
|
+
/** Create, message, and close agent chat sessions. Requires `agent.sessions.*` capabilities. */
|
|
782
|
+
sessions: PluginAgentSessionsClient;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Represents an active conversational session with an agent.
|
|
786
|
+
* Maps to an `AgentTaskSession` row on the host.
|
|
787
|
+
*/
|
|
788
|
+
export interface AgentSession {
|
|
789
|
+
sessionId: string;
|
|
790
|
+
agentId: string;
|
|
791
|
+
companyId: string;
|
|
792
|
+
status: "active" | "closed";
|
|
793
|
+
createdAt: string;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* A streaming event received during a session's `sendMessage` call.
|
|
797
|
+
* Delivered via JSON-RPC notifications from host to worker.
|
|
798
|
+
*/
|
|
799
|
+
export interface AgentSessionEvent {
|
|
800
|
+
sessionId: string;
|
|
801
|
+
runId: string;
|
|
802
|
+
seq: number;
|
|
803
|
+
/** The kind of event: "chunk" for output data, "status" for run state changes, "done" for end-of-stream, "error" for failures. */
|
|
804
|
+
eventType: "chunk" | "status" | "done" | "error";
|
|
805
|
+
stream: "stdout" | "stderr" | "system" | null;
|
|
806
|
+
message: string | null;
|
|
807
|
+
payload: Record<string, unknown> | null;
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Result of sending a message to a session.
|
|
811
|
+
*/
|
|
812
|
+
export interface AgentSessionSendResult {
|
|
813
|
+
runId: string;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* `ctx.agents.sessions` — create, message, and close agent chat sessions.
|
|
817
|
+
*
|
|
818
|
+
* Requires `agent.sessions.create` for create, `agent.sessions.list` for list,
|
|
819
|
+
* `agent.sessions.send` for sendMessage, `agent.sessions.close` for close.
|
|
820
|
+
*/
|
|
821
|
+
export interface PluginAgentSessionsClient {
|
|
822
|
+
/** Create a new conversational session with an agent. Requires `agent.sessions.create`. */
|
|
823
|
+
create(agentId: string, companyId: string, opts?: {
|
|
824
|
+
taskKey?: string;
|
|
825
|
+
reason?: string;
|
|
826
|
+
}): Promise<AgentSession>;
|
|
827
|
+
/** List active sessions for an agent owned by this plugin. Requires `agent.sessions.list`. */
|
|
828
|
+
list(agentId: string, companyId: string): Promise<AgentSession[]>;
|
|
829
|
+
/**
|
|
830
|
+
* Send a message to a session and receive streaming events via the `onEvent` callback.
|
|
831
|
+
* Returns immediately with `{ runId }`. Events are delivered asynchronously.
|
|
832
|
+
* Requires `agent.sessions.send`.
|
|
833
|
+
*/
|
|
834
|
+
sendMessage(sessionId: string, companyId: string, opts: {
|
|
835
|
+
prompt: string;
|
|
836
|
+
reason?: string;
|
|
837
|
+
onEvent?: (event: AgentSessionEvent) => void;
|
|
838
|
+
}): Promise<AgentSessionSendResult>;
|
|
839
|
+
/** Close a session, releasing resources. Requires `agent.sessions.close`. */
|
|
840
|
+
close(sessionId: string, companyId: string): Promise<void>;
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* `ctx.goals` — read and mutate goals.
|
|
844
|
+
*
|
|
845
|
+
* Requires:
|
|
846
|
+
* - `goals.read` for read operations
|
|
847
|
+
* - `goals.create` for create
|
|
848
|
+
* - `goals.update` for update
|
|
849
|
+
*/
|
|
850
|
+
export interface PluginGoalsClient {
|
|
851
|
+
list(input: {
|
|
852
|
+
companyId: string;
|
|
853
|
+
level?: Goal["level"];
|
|
854
|
+
status?: Goal["status"];
|
|
855
|
+
limit?: number;
|
|
856
|
+
offset?: number;
|
|
857
|
+
}): Promise<Goal[]>;
|
|
858
|
+
get(goalId: string, companyId: string): Promise<Goal | null>;
|
|
859
|
+
create(input: {
|
|
860
|
+
companyId: string;
|
|
861
|
+
title: string;
|
|
862
|
+
description?: string;
|
|
863
|
+
level?: Goal["level"];
|
|
864
|
+
status?: Goal["status"];
|
|
865
|
+
parentId?: string;
|
|
866
|
+
ownerAgentId?: string;
|
|
867
|
+
}): Promise<Goal>;
|
|
868
|
+
update(goalId: string, patch: Partial<Pick<Goal, "title" | "description" | "level" | "status" | "parentId" | "ownerAgentId">>, companyId: string): Promise<Goal>;
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* `ctx.streams` — push real-time events from the worker to the plugin UI.
|
|
872
|
+
*
|
|
873
|
+
* The worker opens a named channel, emits events on it, and closes it when
|
|
874
|
+
* done. On the UI side, `usePluginStream(channel)` receives these events in
|
|
875
|
+
* real time via SSE.
|
|
876
|
+
*
|
|
877
|
+
* Streams are scoped to `(pluginId, channel, companyId)`. Multiple UI clients
|
|
878
|
+
* can subscribe to the same channel concurrently.
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```ts
|
|
882
|
+
* // Worker: stream chat tokens to the UI
|
|
883
|
+
* ctx.streams.open("chat", companyId);
|
|
884
|
+
* for await (const token of tokenStream) {
|
|
885
|
+
* ctx.streams.emit("chat", { type: "token", text: token });
|
|
886
|
+
* }
|
|
887
|
+
* ctx.streams.close("chat");
|
|
888
|
+
* ```
|
|
889
|
+
*
|
|
890
|
+
* @see usePluginStream in `@paperclipai/plugin-sdk/ui`
|
|
891
|
+
*/
|
|
892
|
+
export interface PluginStreamsClient {
|
|
893
|
+
/**
|
|
894
|
+
* Open a named stream channel. Optional — `emit()` implicitly opens if needed.
|
|
895
|
+
* Sends a `stream:open` event to connected UI clients.
|
|
896
|
+
*/
|
|
897
|
+
open(channel: string, companyId: string): void;
|
|
898
|
+
/**
|
|
899
|
+
* Push an event to all UI clients subscribed to this channel.
|
|
900
|
+
*
|
|
901
|
+
* @param channel - Stream channel name (e.g. `"chat"`, `"logs"`)
|
|
902
|
+
* @param event - JSON-serializable event payload
|
|
903
|
+
*/
|
|
904
|
+
emit(channel: string, event: unknown): void;
|
|
905
|
+
/**
|
|
906
|
+
* Close a stream channel. Sends a `stream:close` event to connected UI
|
|
907
|
+
* clients so they know no more events will arrive.
|
|
908
|
+
*/
|
|
909
|
+
close(channel: string): void;
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* The full plugin context object passed to the plugin worker at initialisation.
|
|
913
|
+
*
|
|
914
|
+
* This is the central interface plugin authors use to interact with the host.
|
|
915
|
+
* Every client is capability-gated: calling a client method without the
|
|
916
|
+
* required capability declared in the manifest results in a runtime error.
|
|
917
|
+
*
|
|
918
|
+
* @example
|
|
919
|
+
* ```ts
|
|
920
|
+
* import { definePlugin } from "@paperclipai/plugin-sdk";
|
|
921
|
+
*
|
|
922
|
+
* export default definePlugin({
|
|
923
|
+
* async setup(ctx) {
|
|
924
|
+
* ctx.events.on("issue.created", async (event) => {
|
|
925
|
+
* ctx.logger.info("Issue created", { issueId: event.entityId });
|
|
926
|
+
* });
|
|
927
|
+
*
|
|
928
|
+
* ctx.data.register("sync-health", async ({ companyId }) => {
|
|
929
|
+
* const state = await ctx.state.get({ scopeKind: "company", scopeId: String(companyId), stateKey: "last-sync" });
|
|
930
|
+
* return { lastSync: state };
|
|
931
|
+
* });
|
|
932
|
+
* },
|
|
933
|
+
* });
|
|
934
|
+
* ```
|
|
935
|
+
*
|
|
936
|
+
* @see PLUGIN_SPEC.md §14 — SDK Surface
|
|
937
|
+
*/
|
|
938
|
+
export interface PluginContext {
|
|
939
|
+
/** The plugin's manifest as validated at install time. */
|
|
940
|
+
manifest: PaperclipPluginManifestV1;
|
|
941
|
+
/** Read resolved operator configuration. */
|
|
942
|
+
config: PluginConfigClient;
|
|
943
|
+
/** Subscribe to and emit domain events. Requires `events.subscribe` / `events.emit`. */
|
|
944
|
+
events: PluginEventsClient;
|
|
945
|
+
/** Register handlers for scheduled jobs. Requires `jobs.schedule`. */
|
|
946
|
+
jobs: PluginJobsClient;
|
|
947
|
+
/** Register launcher metadata that the host can surface in plugin UI entry points. */
|
|
948
|
+
launchers: PluginLaunchersClient;
|
|
949
|
+
/** Make outbound HTTP requests. Requires `http.outbound`. */
|
|
950
|
+
http: PluginHttpClient;
|
|
951
|
+
/** Resolve secret references. Requires `secrets.read-ref`. */
|
|
952
|
+
secrets: PluginSecretsClient;
|
|
953
|
+
/** Write activity log entries. Requires `activity.log.write`. */
|
|
954
|
+
activity: PluginActivityClient;
|
|
955
|
+
/** Read and write scoped plugin state. Requires `plugin.state.read` / `plugin.state.write`. */
|
|
956
|
+
state: PluginStateClient;
|
|
957
|
+
/** Create and query plugin-owned entity records. */
|
|
958
|
+
entities: PluginEntitiesClient;
|
|
959
|
+
/** Read project and workspace metadata. Requires `projects.read` / `project.workspaces.read`. */
|
|
960
|
+
projects: PluginProjectsClient;
|
|
961
|
+
/** Read company metadata. Requires `companies.read`. */
|
|
962
|
+
companies: PluginCompaniesClient;
|
|
963
|
+
/** Read and write issues, comments, and documents. Requires issue capabilities. */
|
|
964
|
+
issues: PluginIssuesClient;
|
|
965
|
+
/** Read and manage agents. Requires `agents.read` for reads; `agents.pause` / `agents.resume` / `agents.invoke` for write ops. */
|
|
966
|
+
agents: PluginAgentsClient;
|
|
967
|
+
/** Read and mutate goals. Requires `goals.read` for reads; `goals.create` / `goals.update` for write ops. */
|
|
968
|
+
goals: PluginGoalsClient;
|
|
969
|
+
/** Register getData handlers for the plugin's UI components. */
|
|
970
|
+
data: PluginDataClient;
|
|
971
|
+
/** Register performAction handlers for the plugin's UI components. */
|
|
972
|
+
actions: PluginActionsClient;
|
|
973
|
+
/** Push real-time events from the worker to the plugin UI via SSE. */
|
|
974
|
+
streams: PluginStreamsClient;
|
|
975
|
+
/** Register agent tool handlers. Requires `agent.tools.register`. */
|
|
976
|
+
tools: PluginToolsClient;
|
|
977
|
+
/** Write plugin metrics. Requires `metrics.write`. */
|
|
978
|
+
metrics: PluginMetricsClient;
|
|
979
|
+
/** Structured logger. Output is captured and surfaced in the plugin health dashboard. */
|
|
980
|
+
logger: PluginLogger;
|
|
981
|
+
}
|
|
982
|
+
//# sourceMappingURL=types.d.ts.map
|