Initial commit: Paperclip plugin for Legal AI integration
16 agent tools, event handler for auto-linking, sync job every 15m. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
297
node_modules/@paperclipai/plugin-sdk/dist/protocol.js
generated
vendored
Normal file
297
node_modules/@paperclipai/plugin-sdk/dist/protocol.js
generated
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* JSON-RPC 2.0 message types and protocol helpers for the host ↔ worker IPC
|
||||
* channel.
|
||||
*
|
||||
* The Paperclip plugin runtime uses JSON-RPC 2.0 over stdio to communicate
|
||||
* between the host process and each plugin worker process. This module defines:
|
||||
*
|
||||
* - Core JSON-RPC 2.0 envelope types (request, response, notification, error)
|
||||
* - Standard and plugin-specific error codes
|
||||
* - Typed method maps for host→worker and worker→host calls
|
||||
* - Helper functions for creating well-formed messages
|
||||
*
|
||||
* @see PLUGIN_SPEC.md §12.1 — Process Model
|
||||
* @see PLUGIN_SPEC.md §13 — Host-Worker Protocol
|
||||
* @see https://www.jsonrpc.org/specification
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
// JSON-RPC 2.0 — Core Protocol Types
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The JSON-RPC protocol version. Always `"2.0"`. */
|
||||
export const JSONRPC_VERSION = "2.0";
|
||||
// ---------------------------------------------------------------------------
|
||||
// Error Codes
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Standard JSON-RPC 2.0 error codes.
|
||||
*
|
||||
* @see https://www.jsonrpc.org/specification#error_object
|
||||
*/
|
||||
export const JSONRPC_ERROR_CODES = {
|
||||
/** Invalid JSON was received by the server. */
|
||||
PARSE_ERROR: -32700,
|
||||
/** The JSON sent is not a valid Request object. */
|
||||
INVALID_REQUEST: -32600,
|
||||
/** The method does not exist or is not available. */
|
||||
METHOD_NOT_FOUND: -32601,
|
||||
/** Invalid method parameter(s). */
|
||||
INVALID_PARAMS: -32602,
|
||||
/** Internal JSON-RPC error. */
|
||||
INTERNAL_ERROR: -32603,
|
||||
};
|
||||
/**
|
||||
* Paperclip plugin-specific error codes.
|
||||
*
|
||||
* These live in the JSON-RPC "server error" reserved range (-32000 to -32099)
|
||||
* as specified by JSON-RPC 2.0 for implementation-defined server errors.
|
||||
*
|
||||
* @see PLUGIN_SPEC.md §19.7 — Error Propagation Through The Bridge
|
||||
*/
|
||||
export const PLUGIN_RPC_ERROR_CODES = {
|
||||
/** The worker process is not running or not reachable. */
|
||||
WORKER_UNAVAILABLE: -32000,
|
||||
/** The plugin does not have the required capability for this operation. */
|
||||
CAPABILITY_DENIED: -32001,
|
||||
/** The worker reported an unhandled error during method execution. */
|
||||
WORKER_ERROR: -32002,
|
||||
/** The method call timed out waiting for the worker response. */
|
||||
TIMEOUT: -32003,
|
||||
/** The worker does not implement the requested optional method. */
|
||||
METHOD_NOT_IMPLEMENTED: -32004,
|
||||
/** A catch-all for errors that do not fit other categories. */
|
||||
UNKNOWN: -32099,
|
||||
};
|
||||
/** Required methods the worker MUST implement. */
|
||||
export const HOST_TO_WORKER_REQUIRED_METHODS = [
|
||||
"initialize",
|
||||
"health",
|
||||
"shutdown",
|
||||
];
|
||||
/** Optional methods the worker MAY implement. */
|
||||
export const HOST_TO_WORKER_OPTIONAL_METHODS = [
|
||||
"validateConfig",
|
||||
"configChanged",
|
||||
"onEvent",
|
||||
"runJob",
|
||||
"handleWebhook",
|
||||
"getData",
|
||||
"performAction",
|
||||
"executeTool",
|
||||
];
|
||||
// ---------------------------------------------------------------------------
|
||||
// Message Factory Functions
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Counter for generating unique request IDs when no explicit ID is provided. */
|
||||
let _nextId = 1;
|
||||
/** Wrap around before reaching Number.MAX_SAFE_INTEGER to prevent precision loss. */
|
||||
const MAX_SAFE_RPC_ID = Number.MAX_SAFE_INTEGER - 1;
|
||||
/**
|
||||
* Create a JSON-RPC 2.0 request message.
|
||||
*
|
||||
* @param method - The RPC method name
|
||||
* @param params - Structured parameters
|
||||
* @param id - Optional explicit request ID (auto-generated if omitted)
|
||||
*/
|
||||
export function createRequest(method, params, id) {
|
||||
if (_nextId >= MAX_SAFE_RPC_ID) {
|
||||
_nextId = 1;
|
||||
}
|
||||
return {
|
||||
jsonrpc: JSONRPC_VERSION,
|
||||
id: id ?? _nextId++,
|
||||
method,
|
||||
params,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a JSON-RPC 2.0 success response.
|
||||
*
|
||||
* @param id - The request ID being responded to
|
||||
* @param result - The result value
|
||||
*/
|
||||
export function createSuccessResponse(id, result) {
|
||||
return {
|
||||
jsonrpc: JSONRPC_VERSION,
|
||||
id,
|
||||
result,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a JSON-RPC 2.0 error response.
|
||||
*
|
||||
* @param id - The request ID being responded to (null if the request ID could not be determined)
|
||||
* @param code - Machine-readable error code
|
||||
* @param message - Human-readable error message
|
||||
* @param data - Optional structured error data
|
||||
*/
|
||||
export function createErrorResponse(id, code, message, data) {
|
||||
const response = {
|
||||
jsonrpc: JSONRPC_VERSION,
|
||||
id,
|
||||
error: data !== undefined
|
||||
? { code, message, data }
|
||||
: { code, message },
|
||||
};
|
||||
return response;
|
||||
}
|
||||
/**
|
||||
* Create a JSON-RPC 2.0 notification (fire-and-forget, no response expected).
|
||||
*
|
||||
* @param method - The notification method name
|
||||
* @param params - Structured parameters
|
||||
*/
|
||||
export function createNotification(method, params) {
|
||||
return {
|
||||
jsonrpc: JSONRPC_VERSION,
|
||||
method,
|
||||
params,
|
||||
};
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Type Guards
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Check whether a value is a well-formed JSON-RPC 2.0 request.
|
||||
*
|
||||
* A request has `jsonrpc: "2.0"`, a string `method`, and an `id`.
|
||||
*/
|
||||
export function isJsonRpcRequest(value) {
|
||||
if (typeof value !== "object" || value === null)
|
||||
return false;
|
||||
const obj = value;
|
||||
return (obj.jsonrpc === JSONRPC_VERSION &&
|
||||
typeof obj.method === "string" &&
|
||||
"id" in obj &&
|
||||
obj.id !== undefined &&
|
||||
obj.id !== null);
|
||||
}
|
||||
/**
|
||||
* Check whether a value is a well-formed JSON-RPC 2.0 notification.
|
||||
*
|
||||
* A notification has `jsonrpc: "2.0"`, a string `method`, but no `id`.
|
||||
*/
|
||||
export function isJsonRpcNotification(value) {
|
||||
if (typeof value !== "object" || value === null)
|
||||
return false;
|
||||
const obj = value;
|
||||
return (obj.jsonrpc === JSONRPC_VERSION &&
|
||||
typeof obj.method === "string" &&
|
||||
!("id" in obj));
|
||||
}
|
||||
/**
|
||||
* Check whether a value is a well-formed JSON-RPC 2.0 response (success or error).
|
||||
*/
|
||||
export function isJsonRpcResponse(value) {
|
||||
if (typeof value !== "object" || value === null)
|
||||
return false;
|
||||
const obj = value;
|
||||
return (obj.jsonrpc === JSONRPC_VERSION &&
|
||||
"id" in obj &&
|
||||
("result" in obj || "error" in obj));
|
||||
}
|
||||
/**
|
||||
* Check whether a JSON-RPC response is a success response.
|
||||
*/
|
||||
export function isJsonRpcSuccessResponse(response) {
|
||||
return "result" in response && !("error" in response && response.error !== undefined);
|
||||
}
|
||||
/**
|
||||
* Check whether a JSON-RPC response is an error response.
|
||||
*/
|
||||
export function isJsonRpcErrorResponse(response) {
|
||||
return "error" in response && response.error !== undefined;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Serialization Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Line delimiter for JSON-RPC messages over stdio.
|
||||
*
|
||||
* Each message is a single line of JSON terminated by a newline character.
|
||||
* This follows the newline-delimited JSON (NDJSON) convention.
|
||||
*/
|
||||
export const MESSAGE_DELIMITER = "\n";
|
||||
/**
|
||||
* Serialize a JSON-RPC message to a newline-delimited string for transmission
|
||||
* over stdio.
|
||||
*
|
||||
* @param message - Any JSON-RPC message (request, response, or notification)
|
||||
* @returns The JSON string terminated with a newline
|
||||
*/
|
||||
export function serializeMessage(message) {
|
||||
return JSON.stringify(message) + MESSAGE_DELIMITER;
|
||||
}
|
||||
/**
|
||||
* Parse a JSON string into a JSON-RPC message.
|
||||
*
|
||||
* Returns the parsed message or throws a `JsonRpcParseError` if the input
|
||||
* is not valid JSON or does not conform to the JSON-RPC 2.0 structure.
|
||||
*
|
||||
* @param line - A single line of JSON text (with or without trailing newline)
|
||||
* @returns The parsed JSON-RPC message
|
||||
* @throws {JsonRpcParseError} If parsing fails
|
||||
*/
|
||||
export function parseMessage(line) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.length === 0) {
|
||||
throw new JsonRpcParseError("Empty message");
|
||||
}
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(trimmed);
|
||||
}
|
||||
catch {
|
||||
throw new JsonRpcParseError(`Invalid JSON: ${trimmed.slice(0, 200)}`);
|
||||
}
|
||||
if (typeof parsed !== "object" || parsed === null) {
|
||||
throw new JsonRpcParseError("Message must be a JSON object");
|
||||
}
|
||||
const obj = parsed;
|
||||
if (obj.jsonrpc !== JSONRPC_VERSION) {
|
||||
throw new JsonRpcParseError(`Invalid or missing jsonrpc version (expected "${JSONRPC_VERSION}", got ${JSON.stringify(obj.jsonrpc)})`);
|
||||
}
|
||||
// It's a valid JSON-RPC 2.0 envelope — return as-is and let the caller
|
||||
// use the type guards for more specific classification.
|
||||
return parsed;
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Error Classes
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Error thrown when a JSON-RPC message cannot be parsed.
|
||||
*/
|
||||
export class JsonRpcParseError extends Error {
|
||||
name = "JsonRpcParseError";
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Error thrown when a JSON-RPC call fails with a structured error response.
|
||||
*
|
||||
* Captures the full `JsonRpcError` so callers can inspect the code and data.
|
||||
*/
|
||||
export class JsonRpcCallError extends Error {
|
||||
name = "JsonRpcCallError";
|
||||
/** The JSON-RPC error code. */
|
||||
code;
|
||||
/** Optional structured error data from the response. */
|
||||
data;
|
||||
constructor(error) {
|
||||
super(error.message);
|
||||
this.code = error.code;
|
||||
this.data = error.data;
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Reset helper (testing only)
|
||||
// ---------------------------------------------------------------------------
|
||||
/**
|
||||
* Reset the internal request ID counter. **For testing only.**
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function _resetIdCounter() {
|
||||
_nextId = 1;
|
||||
}
|
||||
//# sourceMappingURL=protocol.js.map
|
||||
Reference in New Issue
Block a user