@floegence/redevplugin-ui 0.1.6 → 0.2.2

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.
@@ -0,0 +1,328 @@
1
+ import { PluginBridgeError } from "./errors.js";
2
+ import { pluginUIProtocolVersion } from "./contracts.gen.js";
3
+ import { type OpaqueSurfaceAllowedTag } from "./opaque-surface-policy.gen.js";
4
+ import { type FetchLike } from "./http.js";
5
+ import { type PluginSurfaceScope } from "./surface-scope.js";
6
+ export declare const opaqueSurfaceDocumentSchemaVersion: "redevplugin.opaque_surface_document.v1";
7
+ export declare const pluginRiskPlanSchemaVersion: "redevplugin.capability.risk_plan.v1";
8
+ export type PluginJSONValue = null | boolean | number | string | PluginJSONValue[] | PluginJSONObject;
9
+ export type PluginJSONObject = {
10
+ [key: string]: PluginJSONValue;
11
+ };
12
+ export type BridgeLifecycleEvent = {
13
+ type: "ready";
14
+ } | {
15
+ type: "visible";
16
+ } | {
17
+ type: "hidden";
18
+ } | {
19
+ type: "dispose";
20
+ };
21
+ export type TrustedParentBridgeHandshake = {
22
+ type: "redevplugin.bridge.handshake";
23
+ plugin_id: string;
24
+ surface_id: string;
25
+ surface_instance_id: string;
26
+ active_fingerprint: string;
27
+ bridge_nonce: string;
28
+ asset_session_nonce: string;
29
+ plugin_state_version: number;
30
+ revoke_epoch: number;
31
+ ui_protocol_version: typeof pluginUIProtocolVersion;
32
+ };
33
+ export type TrustedParentBridgeTokenRequest = {
34
+ bridge_channel_id: string;
35
+ handshake: TrustedParentBridgeHandshake;
36
+ handshake_transcript_sha256: string;
37
+ previous_plugin_gateway_token?: string;
38
+ };
39
+ export type PluginBridgeRequest = {
40
+ id: string;
41
+ method: string;
42
+ params?: PluginJSONObject;
43
+ };
44
+ export type PluginBridgeResponse = {
45
+ type: "redevplugin.bridge.response";
46
+ id: string;
47
+ ok: true;
48
+ data?: unknown;
49
+ } | {
50
+ type: "redevplugin.bridge.response";
51
+ id: string;
52
+ ok: false;
53
+ error_code: string;
54
+ error: string;
55
+ };
56
+ export type PluginBridgeCancelMessage = {
57
+ type: "redevplugin.bridge.cancel";
58
+ id: string;
59
+ };
60
+ export type PluginBridgeLifecycleMessage = {
61
+ type: "redevplugin.bridge.lifecycle";
62
+ event: BridgeLifecycleEvent;
63
+ };
64
+ export type PluginUIActionEvent = {
65
+ action: string;
66
+ event: "click" | "input" | "change" | "submit";
67
+ value?: string;
68
+ checked?: boolean;
69
+ form_data?: Record<string, string>;
70
+ };
71
+ export type PluginUIAttributeValue = string | number | boolean;
72
+ export type PluginUIVNode = string | {
73
+ type: "element";
74
+ tag: OpaqueSurfaceAllowedTag;
75
+ attributes?: Record<string, PluginUIAttributeValue>;
76
+ children?: PluginUIVNode[];
77
+ };
78
+ export type PluginMethodResult<T = unknown> = {
79
+ data?: T;
80
+ operation_id?: string;
81
+ stream_handle?: string;
82
+ confirmation_required?: boolean;
83
+ confirmation_token_id?: string;
84
+ request_hash?: string;
85
+ };
86
+ export type PluginTrustedMethodResult<T = unknown> = Omit<PluginMethodResult<T>, "stream_handle"> & {
87
+ stream_id?: string;
88
+ stream_ticket?: string;
89
+ stream_ticket_id?: string;
90
+ stream_expires_at?: string;
91
+ };
92
+ export type PluginStreamEvent = {
93
+ stream_id: string;
94
+ sequence: number;
95
+ kind: string;
96
+ data?: string;
97
+ error?: string;
98
+ at: string;
99
+ };
100
+ export type PluginRiskSeverity = "info" | "low" | "medium" | "high" | "critical";
101
+ export type PluginRiskEffect = "read" | "write" | "execute" | "delete" | "admin";
102
+ export type PluginRiskFlag = {
103
+ id: string;
104
+ severity: PluginRiskSeverity;
105
+ summary: string;
106
+ description?: string;
107
+ requires_confirmation?: boolean;
108
+ requires_admin?: boolean;
109
+ data_loss_risk?: boolean;
110
+ destructive?: boolean;
111
+ };
112
+ export type PluginRiskPlan = {
113
+ schema_version: typeof pluginRiskPlanSchemaVersion;
114
+ capability_id?: string;
115
+ binding_id?: string;
116
+ method?: string;
117
+ target_method?: string;
118
+ action?: string;
119
+ effect?: PluginRiskEffect;
120
+ resource_ref?: string;
121
+ resource_display_name?: string;
122
+ summary: string;
123
+ risk_flags: PluginRiskFlag[];
124
+ requires_confirmation?: boolean;
125
+ requires_admin?: boolean;
126
+ data_loss_risk?: boolean;
127
+ destructive?: boolean;
128
+ deny_reason?: string;
129
+ details?: Record<string, unknown>;
130
+ };
131
+ export type PluginConfirmationPlan = PluginRiskPlan | Record<string, unknown>;
132
+ export type PluginConfirmationIntent = {
133
+ requestId: string;
134
+ method: string;
135
+ params?: Record<string, unknown>;
136
+ requestHash: string;
137
+ planHash: string;
138
+ plan?: PluginConfirmationPlan;
139
+ confirmationTokenId: string;
140
+ signal: AbortSignal;
141
+ };
142
+ export type PluginConfirmationDecision = boolean | {
143
+ confirmed: boolean;
144
+ };
145
+ export type PluginConfirmationHandler = (intent: PluginConfirmationIntent) => Promise<PluginConfirmationDecision> | PluginConfirmationDecision;
146
+ export type MessageEventLike = {
147
+ origin?: string;
148
+ data: unknown;
149
+ source?: WindowLike | null;
150
+ ports?: MessagePortLike[];
151
+ };
152
+ export type MessagePortLike = {
153
+ postMessage(message: unknown): void;
154
+ addEventListener(type: "message", listener: (event: MessageEventLike) => void): void;
155
+ removeEventListener(type: "message", listener: (event: MessageEventLike) => void): void;
156
+ start(): void;
157
+ close(): void;
158
+ };
159
+ export type WindowLike = {
160
+ postMessage(message: unknown, targetOrigin: string, transfer?: MessagePortLike[]): void;
161
+ };
162
+ export type MessageChannelLike = {
163
+ port1: MessagePortLike;
164
+ port2: MessagePortLike;
165
+ };
166
+ export type PluginBridgeClientOptions = {
167
+ timeoutMs?: number;
168
+ port?: MessagePortLike;
169
+ surfaceHandle?: string;
170
+ };
171
+ export declare class PluginBridgeClient {
172
+ #private;
173
+ readonly surfaceHandle: string;
174
+ readonly timeoutMs: number;
175
+ constructor(options?: PluginBridgeClientOptions);
176
+ ready(): Promise<void>;
177
+ call<T = unknown>(method: string, params?: PluginJSONObject): Promise<T>;
178
+ readStream(streamHandle: string): Promise<PluginStreamEvent[]>;
179
+ render(tree: PluginUIVNode | PluginUIVNode[]): Promise<void>;
180
+ onAction(action: string, handler: (event: PluginUIActionEvent) => void): () => void;
181
+ onLifecycle(handler: (event: BridgeLifecycleEvent) => void): () => void;
182
+ dispose(): void;
183
+ }
184
+ export declare const defaultPluginSurfaceReloadMax = 2;
185
+ export declare const defaultPluginSurfaceReloadWindowMs = 30000;
186
+ export type PluginSurfaceReloadLimiterOptions = {
187
+ maxReloads?: number;
188
+ windowMs?: number;
189
+ now?: () => number;
190
+ };
191
+ export type PluginSurfaceReloadDecision = {
192
+ allowed: true;
193
+ attempt: number;
194
+ remaining: number;
195
+ windowStartedAtMs: number;
196
+ } | {
197
+ allowed: false;
198
+ attempt: number;
199
+ remaining: 0;
200
+ windowStartedAtMs: number;
201
+ nextRetryAtMs: number;
202
+ reason: "reload_limit_exceeded";
203
+ };
204
+ export type PluginSurfaceReloadState = {
205
+ reloads: number;
206
+ remaining: number;
207
+ windowStartedAtMs?: number;
208
+ nextRetryAtMs?: number;
209
+ };
210
+ export declare class PluginSurfaceReloadLimiter {
211
+ #private;
212
+ readonly maxReloads: number;
213
+ readonly windowMs: number;
214
+ constructor(options?: PluginSurfaceReloadLimiterOptions);
215
+ recordCrash(nowMs?: number): PluginSurfaceReloadDecision;
216
+ recordHealthyLoad(): void;
217
+ reset(): void;
218
+ get state(): PluginSurfaceReloadState;
219
+ }
220
+ export declare function isPluginRiskPlan(plan: unknown): plan is PluginRiskPlan;
221
+ export declare function decodePluginStreamText(event: PluginStreamEvent): string;
222
+ export declare function trustedParentBridgeHandshakeTranscriptSHA256(handshake: TrustedParentBridgeHandshake, bridgeChannelID: string): Promise<string>;
223
+ export type OpaqueSurfaceStyle = {
224
+ path: string;
225
+ sha256: string;
226
+ content: string;
227
+ };
228
+ export type OpaqueSurfaceWorker = {
229
+ path: string;
230
+ sha256: string;
231
+ type: "classic";
232
+ content: string;
233
+ };
234
+ export type OpaqueSurfaceAsset = {
235
+ binding_id: string;
236
+ path: string;
237
+ sha256: string;
238
+ size: number;
239
+ content_type: string;
240
+ };
241
+ export type OpaqueSurfaceDocument = {
242
+ schema_version: typeof opaqueSurfaceDocumentSchemaVersion;
243
+ entry_path: string;
244
+ entry_sha256: string;
245
+ title?: string;
246
+ language?: string;
247
+ direction?: string;
248
+ body_html: string;
249
+ styles: OpaqueSurfaceStyle[];
250
+ worker: OpaqueSurfaceWorker;
251
+ assets: OpaqueSurfaceAsset[];
252
+ critical_bytes: number;
253
+ };
254
+ export type PluginSurfacePreparationResult = {
255
+ asset_session: string;
256
+ asset_session_id: string;
257
+ asset_session_nonce: string;
258
+ entry_path: string;
259
+ entry_sha256: string;
260
+ plugin_state_version: number;
261
+ revoke_epoch: number;
262
+ issued_at: string;
263
+ expires_at: string;
264
+ document: OpaqueSurfaceDocument;
265
+ };
266
+ export type PluginSurfaceHostBootstrap = {
267
+ pluginId: string;
268
+ pluginInstanceId: string;
269
+ pluginVersion: string;
270
+ surfaceId: string;
271
+ surfaceInstanceId: string;
272
+ activeFingerprint: string;
273
+ bridgeNonce: string;
274
+ entryPath: string;
275
+ entrySHA256: string;
276
+ assetTicket: string;
277
+ assetSessionNonce: string;
278
+ pluginStateVersion: number;
279
+ revokeEpoch: number;
280
+ runtimeGenerationId: string;
281
+ };
282
+ export type PluginSurfaceOpeningProgress = {
283
+ phase: "opening";
284
+ elapsedMs: number;
285
+ };
286
+ export type PluginSurfaceHostOptions = {
287
+ bootstrap: PluginSurfaceHostBootstrap;
288
+ hostTransport: ReDevPluginSurfaceTransport;
289
+ surfaceScope?: PluginSurfaceScope;
290
+ bridgeChannelId?: string;
291
+ loadTimeoutMs?: number;
292
+ requestTimeoutMs?: number;
293
+ leaseRenewalLeadMs?: number;
294
+ reloadLimiter?: PluginSurfaceReloadLimiter;
295
+ confirm?: PluginConfirmationHandler;
296
+ onOpeningProgress?: (progress: PluginSurfaceOpeningProgress) => void;
297
+ onError?: (error: PluginBridgeError) => void;
298
+ };
299
+ declare const redevPluginSurfaceTransportBrand: unique symbol;
300
+ export type ReDevPluginSurfaceTransport = {
301
+ readonly [redevPluginSurfaceTransportBrand]: true;
302
+ };
303
+ export type ReDevPluginSurfaceTransportOptions = {
304
+ fetch?: FetchLike;
305
+ apiBaseURL?: string;
306
+ };
307
+ export declare function createReDevPluginSurfaceTransport(options?: ReDevPluginSurfaceTransportOptions): ReDevPluginSurfaceTransport;
308
+ export type OpaquePluginBootstrapHTMLOptions = {
309
+ scriptNonce?: string;
310
+ };
311
+ export declare function createOpaquePluginBootstrapHTML(options?: OpaquePluginBootstrapHTMLOptions): string;
312
+ export declare class PluginSurfaceHost {
313
+ #private;
314
+ readonly element: HTMLIFrameElement;
315
+ readonly bootstrap: PluginSurfaceHostBootstrap;
316
+ readonly bridgeChannelId: string;
317
+ readonly frameGenerationId: string;
318
+ readonly surfaceHandle: string;
319
+ static create(options: PluginSurfaceHostOptions): PluginSurfaceHost;
320
+ private constructor();
321
+ open(): Promise<void>;
322
+ sendLifecycle(event: Exclude<BridgeLifecycleEvent, {
323
+ type: "ready" | "dispose";
324
+ }>): void;
325
+ close(): Promise<void>;
326
+ dispose(): void;
327
+ }
328
+ export {};