@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
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { createReadStream, existsSync, statSync, watch } from "node:fs";
|
|
2
|
+
import { mkdir, readdir, stat } from "node:fs/promises";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
function contentType(filePath) {
|
|
6
|
+
if (filePath.endsWith(".js"))
|
|
7
|
+
return "text/javascript; charset=utf-8";
|
|
8
|
+
if (filePath.endsWith(".css"))
|
|
9
|
+
return "text/css; charset=utf-8";
|
|
10
|
+
if (filePath.endsWith(".json"))
|
|
11
|
+
return "application/json; charset=utf-8";
|
|
12
|
+
if (filePath.endsWith(".html"))
|
|
13
|
+
return "text/html; charset=utf-8";
|
|
14
|
+
if (filePath.endsWith(".svg"))
|
|
15
|
+
return "image/svg+xml";
|
|
16
|
+
return "application/octet-stream";
|
|
17
|
+
}
|
|
18
|
+
function normalizeFilePath(baseDir, reqPath) {
|
|
19
|
+
const pathname = reqPath.split("?")[0] || "/";
|
|
20
|
+
const resolved = pathname === "/" ? "/index.js" : pathname;
|
|
21
|
+
const absolute = path.resolve(baseDir, `.${resolved}`);
|
|
22
|
+
const normalizedBase = `${path.resolve(baseDir)}${path.sep}`;
|
|
23
|
+
if (!absolute.startsWith(normalizedBase) && absolute !== path.resolve(baseDir)) {
|
|
24
|
+
throw new Error("path traversal blocked");
|
|
25
|
+
}
|
|
26
|
+
return absolute;
|
|
27
|
+
}
|
|
28
|
+
function send404(res) {
|
|
29
|
+
res.statusCode = 404;
|
|
30
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
31
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
32
|
+
}
|
|
33
|
+
function sendJson(res, value) {
|
|
34
|
+
res.statusCode = 200;
|
|
35
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
36
|
+
res.end(JSON.stringify(value));
|
|
37
|
+
}
|
|
38
|
+
async function ensureUiDir(uiDir) {
|
|
39
|
+
if (existsSync(uiDir))
|
|
40
|
+
return;
|
|
41
|
+
await mkdir(uiDir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
async function listFilesRecursive(dir) {
|
|
44
|
+
const out = [];
|
|
45
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
46
|
+
for (const entry of entries) {
|
|
47
|
+
const abs = path.join(dir, entry.name);
|
|
48
|
+
if (entry.isDirectory()) {
|
|
49
|
+
out.push(...await listFilesRecursive(abs));
|
|
50
|
+
}
|
|
51
|
+
else if (entry.isFile()) {
|
|
52
|
+
out.push(abs);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function snapshotSignature(rows) {
|
|
58
|
+
return rows.map((row) => `${row.file}:${Math.trunc(row.mtimeMs)}`).join("|");
|
|
59
|
+
}
|
|
60
|
+
async function startUiWatcher(uiDir, onReload) {
|
|
61
|
+
try {
|
|
62
|
+
// macOS/Windows support recursive native watching.
|
|
63
|
+
const watcher = watch(uiDir, { recursive: true }, (_eventType, filename) => {
|
|
64
|
+
if (!filename)
|
|
65
|
+
return;
|
|
66
|
+
onReload(path.join(uiDir, filename));
|
|
67
|
+
});
|
|
68
|
+
return watcher;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Linux may reject recursive watch. Fall back to polling snapshots.
|
|
72
|
+
let previous = snapshotSignature((await getUiBuildSnapshot(path.dirname(uiDir), path.basename(uiDir))).map((row) => ({
|
|
73
|
+
file: row.file,
|
|
74
|
+
mtimeMs: row.mtimeMs,
|
|
75
|
+
})));
|
|
76
|
+
const timer = setInterval(async () => {
|
|
77
|
+
try {
|
|
78
|
+
const nextRows = await getUiBuildSnapshot(path.dirname(uiDir), path.basename(uiDir));
|
|
79
|
+
const next = snapshotSignature(nextRows);
|
|
80
|
+
if (next === previous)
|
|
81
|
+
return;
|
|
82
|
+
previous = next;
|
|
83
|
+
onReload("__snapshot__");
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Ignore transient read errors while bundlers are writing files.
|
|
87
|
+
}
|
|
88
|
+
}, 500);
|
|
89
|
+
return {
|
|
90
|
+
close() {
|
|
91
|
+
clearInterval(timer);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Start a local static server for plugin UI assets with SSE reload events.
|
|
98
|
+
*
|
|
99
|
+
* Endpoint summary:
|
|
100
|
+
* - `GET /__paperclip__/health` for diagnostics
|
|
101
|
+
* - `GET /__paperclip__/events` for hot-reload stream
|
|
102
|
+
* - Any other path serves files from the configured UI build directory
|
|
103
|
+
*/
|
|
104
|
+
export async function startPluginDevServer(options = {}) {
|
|
105
|
+
const rootDir = path.resolve(options.rootDir ?? process.cwd());
|
|
106
|
+
const uiDir = path.resolve(rootDir, options.uiDir ?? "dist/ui");
|
|
107
|
+
const host = options.host ?? "127.0.0.1";
|
|
108
|
+
const port = options.port ?? 4177;
|
|
109
|
+
await ensureUiDir(uiDir);
|
|
110
|
+
const sseClients = new Set();
|
|
111
|
+
const handleRequest = async (req, res) => {
|
|
112
|
+
const url = req.url ?? "/";
|
|
113
|
+
if (url === "/__paperclip__/health") {
|
|
114
|
+
sendJson(res, { ok: true, rootDir, uiDir });
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (url === "/__paperclip__/events") {
|
|
118
|
+
res.writeHead(200, {
|
|
119
|
+
"Content-Type": "text/event-stream",
|
|
120
|
+
"Cache-Control": "no-cache, no-transform",
|
|
121
|
+
Connection: "keep-alive",
|
|
122
|
+
});
|
|
123
|
+
res.write(`event: connected\ndata: {"ok":true}\n\n`);
|
|
124
|
+
sseClients.add(res);
|
|
125
|
+
req.on("close", () => {
|
|
126
|
+
sseClients.delete(res);
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const filePath = normalizeFilePath(uiDir, url);
|
|
132
|
+
if (!existsSync(filePath) || !statSync(filePath).isFile()) {
|
|
133
|
+
send404(res);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
res.statusCode = 200;
|
|
137
|
+
res.setHeader("Content-Type", contentType(filePath));
|
|
138
|
+
createReadStream(filePath).pipe(res);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
send404(res);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const server = createServer((req, res) => {
|
|
145
|
+
void handleRequest(req, res);
|
|
146
|
+
});
|
|
147
|
+
const notifyReload = (filePath) => {
|
|
148
|
+
const rel = path.relative(uiDir, filePath);
|
|
149
|
+
const payload = JSON.stringify({ type: "reload", file: rel, at: new Date().toISOString() });
|
|
150
|
+
for (const client of sseClients) {
|
|
151
|
+
client.write(`event: reload\ndata: ${payload}\n\n`);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const watcher = await startUiWatcher(uiDir, notifyReload);
|
|
155
|
+
await new Promise((resolve, reject) => {
|
|
156
|
+
server.once("error", reject);
|
|
157
|
+
server.listen(port, host, () => resolve());
|
|
158
|
+
});
|
|
159
|
+
const address = server.address();
|
|
160
|
+
const actualPort = address && typeof address === "object" ? address.port : port;
|
|
161
|
+
return {
|
|
162
|
+
url: `http://${host}:${actualPort}`,
|
|
163
|
+
async close() {
|
|
164
|
+
watcher.close();
|
|
165
|
+
for (const client of sseClients) {
|
|
166
|
+
client.end();
|
|
167
|
+
}
|
|
168
|
+
await new Promise((resolve, reject) => {
|
|
169
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Return a stable file+mtime snapshot for a built plugin UI directory.
|
|
176
|
+
*
|
|
177
|
+
* Used by the polling watcher fallback and useful for tests that need to assert
|
|
178
|
+
* whether a UI build has changed between runs.
|
|
179
|
+
*/
|
|
180
|
+
export async function getUiBuildSnapshot(rootDir, uiDir = "dist/ui") {
|
|
181
|
+
const baseDir = path.resolve(rootDir, uiDir);
|
|
182
|
+
if (!existsSync(baseDir))
|
|
183
|
+
return [];
|
|
184
|
+
const files = await listFilesRecursive(baseDir);
|
|
185
|
+
const rows = await Promise.all(files.map(async (filePath) => {
|
|
186
|
+
const fileStat = await stat(filePath);
|
|
187
|
+
return {
|
|
188
|
+
file: path.relative(baseDir, filePath),
|
|
189
|
+
mtimeMs: fileStat.mtimeMs,
|
|
190
|
+
};
|
|
191
|
+
}));
|
|
192
|
+
return rows.sort((a, b) => a.file.localeCompare(b.file));
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=dev-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-side client factory — creates capability-gated handler maps for
|
|
3
|
+
* servicing worker→host JSON-RPC calls.
|
|
4
|
+
*
|
|
5
|
+
* When a plugin worker calls `ctx.state.get(...)` inside its process, the
|
|
6
|
+
* SDK serializes the call as a JSON-RPC request over stdio. On the host side,
|
|
7
|
+
* the `PluginWorkerManager` receives the request and dispatches it to the
|
|
8
|
+
* handler registered for that method. This module provides a factory that
|
|
9
|
+
* creates those handlers for all `WorkerToHostMethods`, with automatic
|
|
10
|
+
* capability enforcement.
|
|
11
|
+
*
|
|
12
|
+
* ## Design
|
|
13
|
+
*
|
|
14
|
+
* 1. **Capability gating**: Each handler checks the plugin's declared
|
|
15
|
+
* capabilities before executing. If the plugin lacks a required capability,
|
|
16
|
+
* the handler throws a `CapabilityDeniedError` (which the worker manager
|
|
17
|
+
* translates into a JSON-RPC error response with code
|
|
18
|
+
* `CAPABILITY_DENIED`).
|
|
19
|
+
*
|
|
20
|
+
* 2. **Service adapters**: The caller provides a `HostServices` object with
|
|
21
|
+
* concrete implementations of each platform service. The factory wires
|
|
22
|
+
* each handler to the appropriate service method.
|
|
23
|
+
*
|
|
24
|
+
* 3. **Type safety**: The returned handler map is typed as
|
|
25
|
+
* `WorkerToHostHandlers` (from `plugin-worker-manager.ts`) so it plugs
|
|
26
|
+
* directly into `WorkerStartOptions.hostHandlers`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const handlers = createHostClientHandlers({
|
|
31
|
+
* pluginId: "acme.linear",
|
|
32
|
+
* capabilities: manifest.capabilities,
|
|
33
|
+
* services: {
|
|
34
|
+
* config: { get: () => registry.getConfig(pluginId) },
|
|
35
|
+
* state: { get: ..., set: ..., delete: ... },
|
|
36
|
+
* entities: { upsert: ..., list: ... },
|
|
37
|
+
* // ... all services
|
|
38
|
+
* },
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* await workerManager.startWorker("acme.linear", {
|
|
42
|
+
* // ...
|
|
43
|
+
* hostHandlers: handlers,
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @see PLUGIN_SPEC.md §13 — Host-Worker Protocol
|
|
48
|
+
* @see PLUGIN_SPEC.md §15 — Capability Model
|
|
49
|
+
*/
|
|
50
|
+
import type { PluginCapability } from "@paperclipai/shared";
|
|
51
|
+
import type { WorkerToHostMethods, WorkerToHostMethodName } from "./protocol.js";
|
|
52
|
+
/**
|
|
53
|
+
* Thrown when a plugin calls a host method it does not have the capability for.
|
|
54
|
+
*
|
|
55
|
+
* The `code` field is set to `PLUGIN_RPC_ERROR_CODES.CAPABILITY_DENIED` so
|
|
56
|
+
* the worker manager can propagate it as the correct JSON-RPC error code.
|
|
57
|
+
*/
|
|
58
|
+
export declare class CapabilityDeniedError extends Error {
|
|
59
|
+
readonly name = "CapabilityDeniedError";
|
|
60
|
+
readonly code: -32001;
|
|
61
|
+
constructor(pluginId: string, method: string, capability: PluginCapability);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Service adapters that the host must provide. Each property maps to a group
|
|
65
|
+
* of `WorkerToHostMethods`. The factory wires JSON-RPC params to these
|
|
66
|
+
* function signatures.
|
|
67
|
+
*
|
|
68
|
+
* All methods return promises to support async I/O (database, HTTP, etc.).
|
|
69
|
+
*/
|
|
70
|
+
export interface HostServices {
|
|
71
|
+
/** Provides `config.get`. */
|
|
72
|
+
config: {
|
|
73
|
+
get(): Promise<Record<string, unknown>>;
|
|
74
|
+
};
|
|
75
|
+
/** Provides `state.get`, `state.set`, `state.delete`. */
|
|
76
|
+
state: {
|
|
77
|
+
get(params: WorkerToHostMethods["state.get"][0]): Promise<WorkerToHostMethods["state.get"][1]>;
|
|
78
|
+
set(params: WorkerToHostMethods["state.set"][0]): Promise<void>;
|
|
79
|
+
delete(params: WorkerToHostMethods["state.delete"][0]): Promise<void>;
|
|
80
|
+
};
|
|
81
|
+
/** Provides `entities.upsert`, `entities.list`. */
|
|
82
|
+
entities: {
|
|
83
|
+
upsert(params: WorkerToHostMethods["entities.upsert"][0]): Promise<WorkerToHostMethods["entities.upsert"][1]>;
|
|
84
|
+
list(params: WorkerToHostMethods["entities.list"][0]): Promise<WorkerToHostMethods["entities.list"][1]>;
|
|
85
|
+
};
|
|
86
|
+
/** Provides `events.emit` and `events.subscribe`. */
|
|
87
|
+
events: {
|
|
88
|
+
emit(params: WorkerToHostMethods["events.emit"][0]): Promise<void>;
|
|
89
|
+
subscribe(params: WorkerToHostMethods["events.subscribe"][0]): Promise<void>;
|
|
90
|
+
};
|
|
91
|
+
/** Provides `http.fetch`. */
|
|
92
|
+
http: {
|
|
93
|
+
fetch(params: WorkerToHostMethods["http.fetch"][0]): Promise<WorkerToHostMethods["http.fetch"][1]>;
|
|
94
|
+
};
|
|
95
|
+
/** Provides `secrets.resolve`. */
|
|
96
|
+
secrets: {
|
|
97
|
+
resolve(params: WorkerToHostMethods["secrets.resolve"][0]): Promise<string>;
|
|
98
|
+
};
|
|
99
|
+
/** Provides `activity.log`. */
|
|
100
|
+
activity: {
|
|
101
|
+
log(params: {
|
|
102
|
+
companyId: string;
|
|
103
|
+
message: string;
|
|
104
|
+
entityType?: string;
|
|
105
|
+
entityId?: string;
|
|
106
|
+
metadata?: Record<string, unknown>;
|
|
107
|
+
}): Promise<void>;
|
|
108
|
+
};
|
|
109
|
+
/** Provides `metrics.write`. */
|
|
110
|
+
metrics: {
|
|
111
|
+
write(params: WorkerToHostMethods["metrics.write"][0]): Promise<void>;
|
|
112
|
+
};
|
|
113
|
+
/** Provides `log`. */
|
|
114
|
+
logger: {
|
|
115
|
+
log(params: WorkerToHostMethods["log"][0]): Promise<void>;
|
|
116
|
+
};
|
|
117
|
+
/** Provides `companies.list`, `companies.get`. */
|
|
118
|
+
companies: {
|
|
119
|
+
list(params: WorkerToHostMethods["companies.list"][0]): Promise<WorkerToHostMethods["companies.list"][1]>;
|
|
120
|
+
get(params: WorkerToHostMethods["companies.get"][0]): Promise<WorkerToHostMethods["companies.get"][1]>;
|
|
121
|
+
};
|
|
122
|
+
/** Provides `projects.list`, `projects.get`, `projects.listWorkspaces`, `projects.getPrimaryWorkspace`, `projects.getWorkspaceForIssue`. */
|
|
123
|
+
projects: {
|
|
124
|
+
list(params: WorkerToHostMethods["projects.list"][0]): Promise<WorkerToHostMethods["projects.list"][1]>;
|
|
125
|
+
get(params: WorkerToHostMethods["projects.get"][0]): Promise<WorkerToHostMethods["projects.get"][1]>;
|
|
126
|
+
listWorkspaces(params: WorkerToHostMethods["projects.listWorkspaces"][0]): Promise<WorkerToHostMethods["projects.listWorkspaces"][1]>;
|
|
127
|
+
getPrimaryWorkspace(params: WorkerToHostMethods["projects.getPrimaryWorkspace"][0]): Promise<WorkerToHostMethods["projects.getPrimaryWorkspace"][1]>;
|
|
128
|
+
getWorkspaceForIssue(params: WorkerToHostMethods["projects.getWorkspaceForIssue"][0]): Promise<WorkerToHostMethods["projects.getWorkspaceForIssue"][1]>;
|
|
129
|
+
};
|
|
130
|
+
/** Provides `issues.list`, `issues.get`, `issues.create`, `issues.update`, `issues.listComments`, `issues.createComment`. */
|
|
131
|
+
issues: {
|
|
132
|
+
list(params: WorkerToHostMethods["issues.list"][0]): Promise<WorkerToHostMethods["issues.list"][1]>;
|
|
133
|
+
get(params: WorkerToHostMethods["issues.get"][0]): Promise<WorkerToHostMethods["issues.get"][1]>;
|
|
134
|
+
create(params: WorkerToHostMethods["issues.create"][0]): Promise<WorkerToHostMethods["issues.create"][1]>;
|
|
135
|
+
update(params: WorkerToHostMethods["issues.update"][0]): Promise<WorkerToHostMethods["issues.update"][1]>;
|
|
136
|
+
listComments(params: WorkerToHostMethods["issues.listComments"][0]): Promise<WorkerToHostMethods["issues.listComments"][1]>;
|
|
137
|
+
createComment(params: WorkerToHostMethods["issues.createComment"][0]): Promise<WorkerToHostMethods["issues.createComment"][1]>;
|
|
138
|
+
};
|
|
139
|
+
/** Provides `issues.documents.list`, `issues.documents.get`, `issues.documents.upsert`, `issues.documents.delete`. */
|
|
140
|
+
issueDocuments: {
|
|
141
|
+
list(params: WorkerToHostMethods["issues.documents.list"][0]): Promise<WorkerToHostMethods["issues.documents.list"][1]>;
|
|
142
|
+
get(params: WorkerToHostMethods["issues.documents.get"][0]): Promise<WorkerToHostMethods["issues.documents.get"][1]>;
|
|
143
|
+
upsert(params: WorkerToHostMethods["issues.documents.upsert"][0]): Promise<WorkerToHostMethods["issues.documents.upsert"][1]>;
|
|
144
|
+
delete(params: WorkerToHostMethods["issues.documents.delete"][0]): Promise<WorkerToHostMethods["issues.documents.delete"][1]>;
|
|
145
|
+
};
|
|
146
|
+
/** Provides `agents.list`, `agents.get`, `agents.pause`, `agents.resume`, `agents.invoke`. */
|
|
147
|
+
agents: {
|
|
148
|
+
list(params: WorkerToHostMethods["agents.list"][0]): Promise<WorkerToHostMethods["agents.list"][1]>;
|
|
149
|
+
get(params: WorkerToHostMethods["agents.get"][0]): Promise<WorkerToHostMethods["agents.get"][1]>;
|
|
150
|
+
pause(params: WorkerToHostMethods["agents.pause"][0]): Promise<WorkerToHostMethods["agents.pause"][1]>;
|
|
151
|
+
resume(params: WorkerToHostMethods["agents.resume"][0]): Promise<WorkerToHostMethods["agents.resume"][1]>;
|
|
152
|
+
invoke(params: WorkerToHostMethods["agents.invoke"][0]): Promise<WorkerToHostMethods["agents.invoke"][1]>;
|
|
153
|
+
};
|
|
154
|
+
/** Provides `agents.sessions.create`, `agents.sessions.list`, `agents.sessions.sendMessage`, `agents.sessions.close`. */
|
|
155
|
+
agentSessions: {
|
|
156
|
+
create(params: WorkerToHostMethods["agents.sessions.create"][0]): Promise<WorkerToHostMethods["agents.sessions.create"][1]>;
|
|
157
|
+
list(params: WorkerToHostMethods["agents.sessions.list"][0]): Promise<WorkerToHostMethods["agents.sessions.list"][1]>;
|
|
158
|
+
sendMessage(params: WorkerToHostMethods["agents.sessions.sendMessage"][0]): Promise<WorkerToHostMethods["agents.sessions.sendMessage"][1]>;
|
|
159
|
+
close(params: WorkerToHostMethods["agents.sessions.close"][0]): Promise<void>;
|
|
160
|
+
};
|
|
161
|
+
/** Provides `goals.list`, `goals.get`, `goals.create`, `goals.update`. */
|
|
162
|
+
goals: {
|
|
163
|
+
list(params: WorkerToHostMethods["goals.list"][0]): Promise<WorkerToHostMethods["goals.list"][1]>;
|
|
164
|
+
get(params: WorkerToHostMethods["goals.get"][0]): Promise<WorkerToHostMethods["goals.get"][1]>;
|
|
165
|
+
create(params: WorkerToHostMethods["goals.create"][0]): Promise<WorkerToHostMethods["goals.create"][1]>;
|
|
166
|
+
update(params: WorkerToHostMethods["goals.update"][0]): Promise<WorkerToHostMethods["goals.update"][1]>;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Options for `createHostClientHandlers`.
|
|
171
|
+
*/
|
|
172
|
+
export interface HostClientFactoryOptions {
|
|
173
|
+
/** The plugin ID. Used for error messages and logging. */
|
|
174
|
+
pluginId: string;
|
|
175
|
+
/**
|
|
176
|
+
* The capabilities declared by the plugin in its manifest. The factory
|
|
177
|
+
* enforces these at runtime before delegating to the service adapter.
|
|
178
|
+
*/
|
|
179
|
+
capabilities: readonly PluginCapability[];
|
|
180
|
+
/**
|
|
181
|
+
* Concrete implementations of host platform services. Each handler in the
|
|
182
|
+
* returned map delegates to the corresponding service method.
|
|
183
|
+
*/
|
|
184
|
+
services: HostServices;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* A handler function for a specific worker→host method.
|
|
188
|
+
*/
|
|
189
|
+
type HostHandler<M extends WorkerToHostMethodName> = (params: WorkerToHostMethods[M][0]) => Promise<WorkerToHostMethods[M][1]>;
|
|
190
|
+
/**
|
|
191
|
+
* A complete map of all worker→host method handlers.
|
|
192
|
+
*
|
|
193
|
+
* This type matches `WorkerToHostHandlers` from `plugin-worker-manager.ts`
|
|
194
|
+
* but makes every handler required (the factory always provides all handlers).
|
|
195
|
+
*/
|
|
196
|
+
export type HostClientHandlers = {
|
|
197
|
+
[M in WorkerToHostMethodName]: HostHandler<M>;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Create a complete handler map for all worker→host JSON-RPC methods.
|
|
201
|
+
*
|
|
202
|
+
* Each handler:
|
|
203
|
+
* 1. Checks the plugin's declared capabilities against the required capability
|
|
204
|
+
* for the method (if any).
|
|
205
|
+
* 2. Delegates to the corresponding service adapter method.
|
|
206
|
+
* 3. Returns the service result, which is serialized as the JSON-RPC response
|
|
207
|
+
* by the worker manager.
|
|
208
|
+
*
|
|
209
|
+
* If a capability check fails, the handler throws a `CapabilityDeniedError`
|
|
210
|
+
* with code `CAPABILITY_DENIED`. The worker manager catches this and sends a
|
|
211
|
+
* JSON-RPC error response to the worker, which surfaces as a `JsonRpcCallError`
|
|
212
|
+
* in the plugin's SDK client.
|
|
213
|
+
*
|
|
214
|
+
* @param options - Plugin ID, capabilities, and service adapters
|
|
215
|
+
* @returns A handler map suitable for `WorkerStartOptions.hostHandlers`
|
|
216
|
+
*/
|
|
217
|
+
export declare function createHostClientHandlers(options: HostClientFactoryOptions): HostClientHandlers;
|
|
218
|
+
/**
|
|
219
|
+
* Get the capability required for a given worker→host method, or `null` if
|
|
220
|
+
* no capability is required.
|
|
221
|
+
*
|
|
222
|
+
* Useful for inspecting capability requirements without calling the factory.
|
|
223
|
+
*
|
|
224
|
+
* @param method - The worker→host method name
|
|
225
|
+
* @returns The required capability, or `null`
|
|
226
|
+
*/
|
|
227
|
+
export declare function getRequiredCapability(method: WorkerToHostMethodName): PluginCapability | null;
|
|
228
|
+
export {};
|
|
229
|
+
//# sourceMappingURL=host-client-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-client-factory.d.ts","sourceRoot":"","sources":["../src/host-client-factory.ts"],"names":[],"mappings":"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"}
|