@hachej/boring-workspace 0.1.53 → 0.1.55

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,353 @@
1
+ import { B as BoringPackageBoringField, a as BoringPackagePiField } from './manifest-C2vVgH_e.js';
2
+ import { PiPackageSource, PluginSkillSource, ProvisionWorkspaceRuntimeOptions, RuntimeModeId, RuntimeEnvContribution } from '@hachej/boring-agent/server';
3
+ import { FastifyPluginAsync } from 'fastify';
4
+ import { A as AgentTool } from './agent-tool-CB0RQyx9.js';
5
+ import { B as BridgeAuthContext, W as WorkspaceBridgeOperationDefinition, a as WorkspaceBridgeCallRequest, b as WorkspaceBridgeCallResponse, d as BridgeCallerClass } from './workspace-bridge-rpc-A98RA5o6.js';
6
+ import { a as UiCommand, C as CommandResult, W as WorkspaceBridge } from './ui-bridge-BbuUZ5iC.js';
7
+
8
+ type BoringPluginNativeFrontTargetTrust$1 = "local-trusted-native";
9
+ /**
10
+ * Host-owned runtime import target for a plugin front entry.
11
+ *
12
+ * Only the trusted native/browser-module case exists today. Future
13
+ * target kinds (iframe/artifact/...) can extend the union without
14
+ * rewriting list/event payload shapes.
15
+ */
16
+ interface BoringPluginNativeFrontTarget$1 {
17
+ kind: "native";
18
+ entryUrl: string;
19
+ revision: number;
20
+ trust: BoringPluginNativeFrontTargetTrust$1;
21
+ }
22
+ /**
23
+ * Plugin front served as a plain browser module URL — the Vite-dev transport
24
+ * (`/@fs/...`). Hosts running a Vite dev server let Vite transform the entry;
25
+ * the CLI's runtime host mints `native` targets instead.
26
+ */
27
+ interface BoringPluginModuleUrlFrontTarget {
28
+ kind: "module-url";
29
+ entryUrl: string;
30
+ revision: number;
31
+ }
32
+ type BoringPluginFrontTarget$1 = BoringPluginNativeFrontTarget$1 | BoringPluginModuleUrlFrontTarget;
33
+ type BoringPluginEvent$1 = {
34
+ type: "boring.plugin.load";
35
+ id: string;
36
+ boring: BoringPackageBoringField;
37
+ version: string;
38
+ revision: number;
39
+ frontTarget?: BoringPluginFrontTarget$1;
40
+ } | {
41
+ type: "boring.plugin.unload";
42
+ id: string;
43
+ revision: number;
44
+ } | {
45
+ type: "boring.plugin.error";
46
+ id: string;
47
+ revision: number;
48
+ message: string;
49
+ };
50
+ interface BoringPluginListEntry$1 {
51
+ id: string;
52
+ boring: BoringPackageBoringField;
53
+ pi?: BoringPackagePiField;
54
+ version: string;
55
+ revision: number;
56
+ frontTarget?: BoringPluginFrontTarget$1;
57
+ }
58
+
59
+ type BoringPluginSourceKind = "internal" | "external";
60
+ interface BoringPluginSource {
61
+ rootDir: string;
62
+ kind: BoringPluginSourceKind;
63
+ workspaceId?: string;
64
+ /**
65
+ * True when the user explicitly registered this directory as a plugin
66
+ * source (e.g. a `packages` entry in Pi settings.json). Registered
67
+ * sources that are missing, lack a package.json, or carry no plugin
68
+ * metadata surface as preflight errors instead of being silently
69
+ * skipped the way speculative scan roots are.
70
+ */
71
+ registered?: boolean;
72
+ }
73
+ type BoringPluginSourceInput = string | BoringPluginSource;
74
+ interface BoringServerPluginManifest {
75
+ id: string;
76
+ rootDir: string;
77
+ version: string;
78
+ boring: BoringPackageBoringField;
79
+ /** True when package.json explicitly declares a boring manifest. Pi-only packages remain valid Pi resources but are not listed as Boring plugins. */
80
+ hasBoring: boolean;
81
+ pi?: BoringPackagePiField;
82
+ frontPath?: string;
83
+ /** Legacy Vite-dev browser import fallback (`/@fs/...`). */
84
+ frontUrl?: string;
85
+ serverPath?: string;
86
+ extensionPaths?: string[];
87
+ skillPaths?: string[];
88
+ source: BoringPluginSource;
89
+ }
90
+ type BoringPluginNativeFrontTargetTrust = BoringPluginNativeFrontTargetTrust$1;
91
+ type BoringPluginNativeFrontTarget = BoringPluginNativeFrontTarget$1;
92
+ type BoringPluginFrontTarget = BoringPluginFrontTarget$1;
93
+ type BoringPluginListEntry = BoringPluginListEntry$1;
94
+ interface BoringPluginFrontTargetResolverContext {
95
+ revision: number;
96
+ /** Plugin-root-relative front entry path normalized for URL-like consumers. */
97
+ frontEntrySubpath: string;
98
+ }
99
+ type BoringPluginFrontTargetResolver = (plugin: BoringServerPluginManifest, context: BoringPluginFrontTargetResolverContext) => BoringPluginFrontTarget | undefined;
100
+ /**
101
+ * Surfaces whose changes the hot-reload pipeline can't re-load mid-
102
+ * session — set when a plugin's load DID succeed but a sub-surface
103
+ * (the agent-tools registry, Fastify routes) carries stale code from
104
+ * the previous revision. The /reload caller (chat UI, verify-plugin,
105
+ * etc.) should surface a "restart needed for X" warning.
106
+ *
107
+ * - `'routes'`: a `WorkspaceServerPlugin.routes` function changed. The
108
+ * workspace's Fastify instance can't unregister + re-register routes
109
+ * mid-flight; the previous routes stay live until next boot.
110
+ * - `'agentTools'`: a `WorkspaceServerPlugin.agentTools` array changed.
111
+ * The current Pi session still has the old tool list; new sessions
112
+ * get the new list.
113
+ * - Multiple surfaces: order is deterministic (`routes` before
114
+ * `agentTools`) so subscribers can format consistently.
115
+ */
116
+ type PluginRestartSurface = "routes" | "agentTools";
117
+ type BoringPluginEvent = (Extract<BoringPluginEvent$1, {
118
+ type: "boring.plugin.load";
119
+ }> & {
120
+ /**
121
+ * Non-empty when the plugin loaded but one or more server-side
122
+ * surfaces still hold pre-load code. UI consumers should render
123
+ * a "restart needed: <surfaces>" hint. Empty/omitted = fully
124
+ * live.
125
+ */
126
+ requiresRestart?: PluginRestartSurface[];
127
+ }) | Extract<BoringPluginEvent$1, {
128
+ type: "boring.plugin.unload";
129
+ }> | Extract<BoringPluginEvent$1, {
130
+ type: "boring.plugin.error";
131
+ }>;
132
+
133
+ interface WorkspaceBridgeCallContext extends BridgeAuthContext {
134
+ requestId?: string;
135
+ signal?: AbortSignal;
136
+ emitUiEffect?: (cmd: UiCommand) => Promise<CommandResult>;
137
+ }
138
+ interface WorkspaceBridgeHandlerArgs<TInput = unknown> {
139
+ input: TInput;
140
+ context: WorkspaceBridgeCallContext;
141
+ definition: WorkspaceBridgeOperationDefinition<TInput, unknown>;
142
+ signal: AbortSignal;
143
+ emitUiEffect?: WorkspaceBridge["emitUiEffect"];
144
+ }
145
+ type WorkspaceBridgeHandler<TInput = unknown, TOutput = unknown> = (args: WorkspaceBridgeHandlerArgs<TInput>) => TOutput | Promise<TOutput>;
146
+ interface RegisterWorkspaceBridgeHandlerOptions {
147
+ replace?: boolean;
148
+ }
149
+ interface WorkspaceBridgeRegistryLogger {
150
+ debug?(message: string, fields?: Record<string, unknown>): void;
151
+ info?(message: string, fields?: Record<string, unknown>): void;
152
+ warn?(message: string, fields?: Record<string, unknown>): void;
153
+ error?(message: string, fields?: Record<string, unknown>): void;
154
+ }
155
+ interface WorkspaceBridgeRegistryOptions {
156
+ logger?: WorkspaceBridgeRegistryLogger;
157
+ /** Workspace that owns this registry instance. Calls from other workspace ids are rejected unless the op opts into allowCrossWorkspace. */
158
+ ownerWorkspaceId?: string;
159
+ }
160
+ interface WorkspaceBridgeRegistryCallOptions {
161
+ /** Per-call owner override for hosts that reuse a registry across workspaces. */
162
+ expectedWorkspaceId?: string;
163
+ }
164
+ declare function validateWorkspaceBridgeOperationDefinition(definition: WorkspaceBridgeOperationDefinition): void;
165
+ declare class WorkspaceBridgeRegistry {
166
+ private readonly handlers;
167
+ private readonly logger?;
168
+ private readonly ownerWorkspaceId?;
169
+ constructor(options?: WorkspaceBridgeRegistryOptions);
170
+ registerHandler<TInput, TOutput>(definition: WorkspaceBridgeOperationDefinition<TInput, TOutput>, handler: WorkspaceBridgeHandler<TInput, TOutput>, options?: RegisterWorkspaceBridgeHandlerOptions): void;
171
+ getDefinition(op: string): WorkspaceBridgeOperationDefinition | undefined;
172
+ listDefinitions(): WorkspaceBridgeOperationDefinition[];
173
+ call<TInput = unknown, TOutput = unknown>(request: WorkspaceBridgeCallRequest<TInput>, context: WorkspaceBridgeCallContext, options?: WorkspaceBridgeRegistryCallOptions): Promise<WorkspaceBridgeCallResponse<TOutput>>;
174
+ private failure;
175
+ }
176
+ declare function createWorkspaceBridgeRegistry(options?: WorkspaceBridgeRegistryOptions): WorkspaceBridgeRegistry;
177
+
178
+ type WorkspaceRuntimeProvisioning = NonNullable<ProvisionWorkspaceRuntimeOptions["plugins"][number]["provisioning"]>;
179
+ interface WorkspaceServerPluginAsset {
180
+ /** Stable asset name within this plugin, e.g. "sdk" or "workspace-template". */
181
+ name: string;
182
+ /** Source directory or file owned by the plugin. Relative strings are resolved by the app integration. */
183
+ source: string | URL;
184
+ /** Optional runtime target path within this plugin's asset namespace. Defaults to name. */
185
+ target?: string;
186
+ }
187
+ interface WorkspaceBridgeHandlerContribution {
188
+ definition: WorkspaceBridgeOperationDefinition;
189
+ handler: WorkspaceBridgeHandler;
190
+ }
191
+ interface WorkspaceServerPlugin {
192
+ id: string;
193
+ label?: string;
194
+ /**
195
+ * Native Pi package sources required by this workspace integration.
196
+ * Workspace declares them; @hachej/boring-agent applies them through Pi's native
197
+ * resource loader without asking Pi packages to export Boring adapters.
198
+ */
199
+ piPackages?: PiPackageSource[];
200
+ /**
201
+ * Native pi extension entrypoints contributed by this plugin.
202
+ * Passed to DefaultResourceLoader.additionalExtensionPaths so pi owns jiti
203
+ * loading and ctx.reload() re-imports fresh source.
204
+ */
205
+ extensionPaths?: string[];
206
+ systemPrompt?: string;
207
+ skills?: PluginSkillSource[];
208
+ agentTools?: AgentTool[];
209
+ /** Trusted boot-time host RPC handlers. Only app/internal server plugins should provide these. */
210
+ workspaceBridgeHandlers?: WorkspaceBridgeHandlerContribution[];
211
+ provisioning?: WorkspaceRuntimeProvisioning;
212
+ /** Static filesystem assets this plugin needs in production/serverless bundles. */
213
+ assets?: WorkspaceServerPluginAsset[];
214
+ routes?: FastifyPluginAsync;
215
+ /** UI state keys owned by this plugin that browser state PUTs must not overwrite. */
216
+ preservedUiStateKeys?: string[];
217
+ }
218
+ declare function validateServerPlugin(plugin: WorkspaceServerPlugin): void;
219
+ declare function defineServerPlugin<T extends WorkspaceServerPlugin>(plugin: T): T;
220
+
221
+ interface ServerBootstrapOptions {
222
+ plugins?: WorkspaceServerPlugin[];
223
+ defaults?: WorkspaceServerPlugin[];
224
+ excludeDefaults?: string[];
225
+ }
226
+ type WorkspaceRuntimeProvisioningInput = ProvisionWorkspaceRuntimeOptions["plugins"][number];
227
+ type WorkspaceProvisioningContribution = {
228
+ id: string;
229
+ provisioning: NonNullable<WorkspaceRuntimeProvisioningInput["provisioning"]>;
230
+ };
231
+ type WorkspaceRouteContribution = {
232
+ id: string;
233
+ routes: FastifyPluginAsync;
234
+ };
235
+ interface ServerBootstrapResult {
236
+ registered: string[];
237
+ systemPromptAppend: string;
238
+ piPackages: PiPackageSource[];
239
+ extensionPaths: string[];
240
+ agentTools: AgentTool[];
241
+ runtimePlugins: WorkspaceRuntimeProvisioningInput[];
242
+ provisioningContributions: WorkspaceProvisioningContribution[];
243
+ routeContributions: WorkspaceRouteContribution[];
244
+ workspaceBridgeHandlers: WorkspaceBridgeHandlerContribution[];
245
+ preservedUiStateKeys: string[];
246
+ }
247
+ declare function bootstrapServer(options: ServerBootstrapOptions): ServerBootstrapResult;
248
+
249
+ declare function createInMemoryBridge(): WorkspaceBridge;
250
+
251
+ interface BridgePrincipal {
252
+ userId: string;
253
+ email?: string;
254
+ roles?: readonly string[];
255
+ }
256
+ interface BridgeWorkspaceGrant {
257
+ allowed: boolean;
258
+ role?: string;
259
+ capabilities: readonly string[];
260
+ resourceScope?: Record<string, unknown>;
261
+ }
262
+ interface BridgeAuthPolicyRequestLike {
263
+ headers?: Record<string, string | string[] | undefined>;
264
+ method?: string;
265
+ /** Host-authenticated principal attached to the Fastify request, if available. */
266
+ user?: unknown;
267
+ }
268
+ interface BridgeAuthPolicyInput {
269
+ callerClass: BridgeCallerClass;
270
+ definition: WorkspaceBridgeOperationDefinition;
271
+ workspaceId: string;
272
+ sessionId?: string;
273
+ pluginId?: string;
274
+ request?: BridgeAuthPolicyRequestLike;
275
+ body?: unknown;
276
+ requiredCapabilities?: readonly string[];
277
+ }
278
+ interface BridgeAuthResolution {
279
+ context: BridgeAuthContext;
280
+ effectiveCapabilities: readonly string[];
281
+ resourceScope?: Record<string, unknown>;
282
+ principal?: BridgePrincipal;
283
+ }
284
+ interface BridgeAuthPolicy {
285
+ resolve(input: BridgeAuthPolicyInput): Promise<BridgeAuthResolution> | BridgeAuthResolution;
286
+ }
287
+ interface BrowserBridgeAuthPolicyOptions {
288
+ getPrincipal(input: BridgeAuthPolicyInput): Promise<BridgePrincipal | null> | BridgePrincipal | null;
289
+ authorizeWorkspace(input: {
290
+ principal: BridgePrincipal;
291
+ workspaceId: string;
292
+ sessionId?: string;
293
+ definition: WorkspaceBridgeOperationDefinition;
294
+ request?: BridgeAuthPolicyRequestLike;
295
+ }): Promise<BridgeWorkspaceGrant> | BridgeWorkspaceGrant;
296
+ allowedOrigins?: readonly string[];
297
+ /**
298
+ * Require a non-empty x-csrf-token header as a non-simple-request proof.
299
+ * This policy does not validate a signed token value; hosts that need
300
+ * cryptographic CSRF tokens should verify them before/inside getPrincipal.
301
+ */
302
+ requireCsrfHeader?: boolean;
303
+ }
304
+ interface LocalCliBridgeAuthPolicyOptions {
305
+ workspaceId: string;
306
+ capabilities?: readonly string[];
307
+ }
308
+ declare function createBrowserBridgeAuthPolicy(options: BrowserBridgeAuthPolicyOptions): BridgeAuthPolicy;
309
+ /**
310
+ * Dev/local CLI only. This policy performs no user authentication and grants
311
+ * the configured capabilities (defaulting to the op's own) to a fixed
312
+ * local-cli principal. Do not use it for exposed or production servers; pass a
313
+ * host-owned createBrowserBridgeAuthPolicy-style policy instead.
314
+ */
315
+ declare function createLocalCliBridgeAuthPolicy(options: LocalCliBridgeAuthPolicyOptions): BridgeAuthPolicy;
316
+
317
+ type WorkspaceBridgeRuntimeEnvDisabledReason = "bridge-url-missing" | "runtime-token-secret-missing" | "runtime-capabilities-missing" | "remote-bridge-url-must-be-https" | "remote-bridge-url-must-not-be-localhost" | "bridge-url-invalid";
318
+ interface WorkspaceBridgeRuntimeEnvOptions {
319
+ /** Opt in to runtime SDK/CLI bridge env injection. Defaults to true when bridgeUrl is set. */
320
+ enabled?: boolean;
321
+ /** Trusted, externally reachable app origin or full /api/v1/workspace-bridge/call URL. */
322
+ bridgeUrl?: string;
323
+ /** Allow plain HTTP for local/dev endpoints. Remote runtimes still require HTTPS. */
324
+ allowInsecureHttp?: boolean;
325
+ /**
326
+ * Explicit capability strings minted into runtime bridge tokens. These are
327
+ * grants the registry checks at call time, not resource-ownership checks;
328
+ * operation handlers must still enforce their own domain/resource scope.
329
+ */
330
+ capabilities?: readonly string[];
331
+ /** Runtime call-token TTL. Defaults to the token primitive default. */
332
+ tokenTtlMs?: number;
333
+ /** Runtime refresh-token TTL. Defaults to the token primitive default. */
334
+ refreshTokenTtlMs?: number;
335
+ /** Optional audit/session claim. */
336
+ sessionId?: string;
337
+ }
338
+ type WorkspaceBridgeRuntimePlacement = "local" | "remote";
339
+ interface CreateWorkspaceBridgeRuntimeEnvContributionOptions {
340
+ workspaceId: string;
341
+ runtimeMode: RuntimeModeId;
342
+ registry: WorkspaceBridgeRegistry;
343
+ runtimeTokenSecret?: string;
344
+ runtimeRefreshTokenSecret?: string;
345
+ runtimeEnv?: WorkspaceBridgeRuntimeEnvOptions;
346
+ /** Provider-neutral fallback used when getEnv is called without a RuntimeEnvContributionContext (mostly tests). */
347
+ runtimePlacement?: WorkspaceBridgeRuntimePlacement;
348
+ }
349
+ declare function createWorkspaceBridgeRuntimeEnvContribution(options: CreateWorkspaceBridgeRuntimeEnvContributionOptions): RuntimeEnvContribution | undefined;
350
+ declare function resolveBridgeCallUrl(value: string | undefined): string | undefined;
351
+ declare function resolveBridgeTokenUrl(value: string | undefined): string | undefined;
352
+
353
+ export { type WorkspaceBridgeCallContext as A, type BridgeAuthPolicy as B, type CreateWorkspaceBridgeRuntimeEnvContributionOptions as C, type WorkspaceBridgeHandlerArgs as D, type WorkspaceBridgeHandlerContribution as E, type WorkspaceBridgeRegistryCallOptions as F, type WorkspaceBridgeRegistryLogger as G, type WorkspaceBridgeRegistryOptions as H, type WorkspaceBridgeRuntimeEnvDisabledReason as I, type WorkspaceBridgeRuntimePlacement as J, bootstrapServer as K, type LocalCliBridgeAuthPolicyOptions as L, createBrowserBridgeAuthPolicy as M, createLocalCliBridgeAuthPolicy as N, createWorkspaceBridgeRegistry as O, type PluginRestartSurface as P, createWorkspaceBridgeRuntimeEnvContribution as Q, type RegisterWorkspaceBridgeHandlerOptions as R, type ServerBootstrapOptions as S, defineServerPlugin as T, resolveBridgeCallUrl as U, resolveBridgeTokenUrl as V, type WorkspaceServerPlugin as W, validateServerPlugin as X, validateWorkspaceBridgeOperationDefinition as Y, WorkspaceBridgeRegistry as a, type WorkspaceBridgeHandler as b, type WorkspaceBridgeRuntimeEnvOptions as c, type BoringPluginSourceInput as d, type BoringPluginFrontTargetResolver as e, type WorkspaceProvisioningContribution as f, type WorkspaceRouteContribution as g, createInMemoryBridge as h, type WorkspaceRuntimeProvisioningInput as i, type WorkspaceServerPluginAsset as j, type BoringServerPluginManifest as k, type BoringPluginListEntry as l, type BoringPluginFrontTarget as m, type BoringPluginSource as n, type BoringPluginEvent as o, type BoringPluginFrontTargetResolverContext as p, type BoringPluginNativeFrontTarget as q, type BoringPluginNativeFrontTargetTrust as r, type BoringPluginSourceKind as s, type BridgeAuthPolicyInput as t, type BridgeAuthPolicyRequestLike as u, type BridgeAuthResolution as v, type BridgePrincipal as w, type BridgeWorkspaceGrant as x, type BrowserBridgeAuthPolicyOptions as y, type ServerBootstrapResult as z };
package/dist/server.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- import { f as WorkspaceServerPluginAsset, g as BoringServerPluginManifest, B as BoringPluginSourceInput, a as BoringPluginFrontTargetResolver, h as BoringPluginListEntry, i as BoringPluginFrontTarget, j as BoringPluginSource, k as BoringPluginEvent, P as PluginRestartSurface } from './createInMemoryBridge-siFWq_R_.js';
2
- export { l as BoringPluginFrontTargetResolverContext, m as BoringPluginNativeFrontTarget, n as BoringPluginNativeFrontTargetTrust, o as BoringPluginSourceKind, S as ServerBootstrapOptions, p as ServerBootstrapResult, b as WorkspaceProvisioningContribution, c as WorkspaceRouteContribution, W as WorkspaceServerPlugin, q as bootstrapServer, d as createInMemoryBridge, r as defineServerPlugin, v as validateServerPlugin } from './createInMemoryBridge-siFWq_R_.js';
1
+ import { j as WorkspaceServerPluginAsset, a as WorkspaceBridgeRegistry, B as BridgeAuthPolicy, b as WorkspaceBridgeHandler, k as BoringServerPluginManifest, d as BoringPluginSourceInput, e as BoringPluginFrontTargetResolver, l as BoringPluginListEntry, m as BoringPluginFrontTarget, n as BoringPluginSource, o as BoringPluginEvent, P as PluginRestartSurface } from './runtimeEnv-XVFZ1OkV.js';
2
+ export { p as BoringPluginFrontTargetResolverContext, q as BoringPluginNativeFrontTarget, r as BoringPluginNativeFrontTargetTrust, s as BoringPluginSourceKind, t as BridgeAuthPolicyInput, u as BridgeAuthPolicyRequestLike, v as BridgeAuthResolution, w as BridgePrincipal, x as BridgeWorkspaceGrant, y as BrowserBridgeAuthPolicyOptions, C as CreateWorkspaceBridgeRuntimeEnvContributionOptions, L as LocalCliBridgeAuthPolicyOptions, R as RegisterWorkspaceBridgeHandlerOptions, S as ServerBootstrapOptions, z as ServerBootstrapResult, A as WorkspaceBridgeCallContext, D as WorkspaceBridgeHandlerArgs, E as WorkspaceBridgeHandlerContribution, F as WorkspaceBridgeRegistryCallOptions, G as WorkspaceBridgeRegistryLogger, H as WorkspaceBridgeRegistryOptions, I as WorkspaceBridgeRuntimeEnvDisabledReason, c as WorkspaceBridgeRuntimeEnvOptions, J as WorkspaceBridgeRuntimePlacement, f as WorkspaceProvisioningContribution, g as WorkspaceRouteContribution, W as WorkspaceServerPlugin, K as bootstrapServer, M as createBrowserBridgeAuthPolicy, h as createInMemoryBridge, N as createLocalCliBridgeAuthPolicy, O as createWorkspaceBridgeRegistry, Q as createWorkspaceBridgeRuntimeEnvContribution, T as defineServerPlugin, U as resolveBridgeCallUrl, V as resolveBridgeTokenUrl, X as validateServerPlugin, Y as validateWorkspaceBridgeOperationDefinition } from './runtimeEnv-XVFZ1OkV.js';
3
3
  import { FastifyRequest, FastifyInstance } from 'fastify';
4
- import { U as UiBridge } from './ui-bridge-LeBuZqfA.js';
5
- export { C as CommandResult, a as UiCommand, b as UiState } from './ui-bridge-LeBuZqfA.js';
4
+ import { U as UiBridge, W as WorkspaceBridge } from './ui-bridge-BbuUZ5iC.js';
5
+ export { C as CommandResult, a as UiCommand, b as UiState } from './ui-bridge-BbuUZ5iC.js';
6
6
  import { A as AgentTool } from './agent-tool-CB0RQyx9.js';
7
+ import { W as WorkspaceBridgeOperationDefinition, a as WorkspaceBridgeCallRequest, B as BridgeAuthContext, b as WorkspaceBridgeCallResponse, c as WorkspaceBridgeError, d as BridgeCallerClass, e as BridgeIdempotencyPolicy } from './workspace-bridge-rpc-A98RA5o6.js';
8
+ export { f as BridgeActorAttribution, g as BridgeActorKind, h as BridgeRedactedActorRef, i as WorkspaceBridgeCallFailure, j as WorkspaceBridgeCallSuccess, k as WorkspaceBridgeErrorCode, l as WorkspaceBridgeFileAssetPointer, m as WorkspaceBridgeJsonValue, n as createWorkspaceBridgeError } from './workspace-bridge-rpc-A98RA5o6.js';
7
9
  import { PiPackageSource } from '@hachej/boring-agent/server';
8
10
  export { PiPackageSource as WorkspacePiPackageSource } from '@hachej/boring-agent/server';
9
11
  import { PluginLogger } from './runtime-server.js';
@@ -111,8 +113,8 @@ interface ExecUiToolOptions {
111
113
  */
112
114
  verifyIntervalMs?: number;
113
115
  }
114
- declare function createGetUiStateTool(uiBridge: UiBridge): AgentTool;
115
- declare function createExecUiTool(uiBridge: UiBridge, opts?: ExecUiToolOptions): AgentTool;
116
+ declare function createGetUiStateTool(workspaceBridge: WorkspaceBridge): AgentTool;
117
+ declare function createExecUiTool(workspaceBridge: WorkspaceBridge, opts?: ExecUiToolOptions): AgentTool;
116
118
  /**
117
119
  * Convenience: returns both UI tools as an `AgentTool[]` ready to merge into
118
120
  * `extraTools`. `createWorkspaceAgentServer` calls this internally; hosts that
@@ -124,7 +126,233 @@ declare function createExecUiTool(uiBridge: UiBridge, opts?: ExecUiToolOptions):
124
126
  * })
125
127
  * await app.register(uiRoutes, { bridge })
126
128
  */
127
- declare function createWorkspaceUiTools(uiBridge: UiBridge, opts?: ExecUiToolOptions): AgentTool[];
129
+ declare function createWorkspaceUiTools(workspaceBridge: WorkspaceBridge, opts?: ExecUiToolOptions): AgentTool[];
130
+
131
+ declare function stableStringify(value: unknown): string;
132
+
133
+ type IdempotencyRecordStatus = "pending" | "completed";
134
+ interface WorkspaceBridgeIdempotencyRecord<TOutput = unknown> {
135
+ scopeKey: string;
136
+ inputHash: string;
137
+ status: IdempotencyRecordStatus;
138
+ createdAt: string;
139
+ updatedAt: string;
140
+ expiresAt: string;
141
+ response?: WorkspaceBridgeCallResponse<TOutput>;
142
+ }
143
+ type IdempotencyBeginResult<TOutput = unknown> = {
144
+ action: "execute";
145
+ scopeKey: string;
146
+ inputHash: string;
147
+ } | {
148
+ action: "replay";
149
+ record: WorkspaceBridgeIdempotencyRecord<TOutput>;
150
+ } | {
151
+ action: "reject";
152
+ error: WorkspaceBridgeError;
153
+ };
154
+ interface BeginIdempotencyOptions<TInput = unknown> {
155
+ definition: WorkspaceBridgeOperationDefinition<TInput, unknown>;
156
+ request: WorkspaceBridgeCallRequest<TInput>;
157
+ auth: Pick<BridgeAuthContext, "workspaceId" | "sessionId" | "pluginId" | "tokenId">;
158
+ nowMs?: number;
159
+ ttlMs?: number;
160
+ }
161
+ interface CompleteIdempotencyOptions<TOutput = unknown> {
162
+ scopeKey: string;
163
+ inputHash: string;
164
+ response: WorkspaceBridgeCallResponse<TOutput>;
165
+ nowMs?: number;
166
+ ttlMs?: number;
167
+ }
168
+ interface WorkspaceBridgeIdempotencyStore {
169
+ begin<TInput = unknown, TOutput = unknown>(options: BeginIdempotencyOptions<TInput>): Promise<IdempotencyBeginResult<TOutput>>;
170
+ complete<TOutput = unknown>(options: CompleteIdempotencyOptions<TOutput>): Promise<void>;
171
+ /**
172
+ * Release a pending record so the same key can be retried. Used when a
173
+ * mutation fails transiently: caching the failure would otherwise block
174
+ * legitimate same-key retries until the record's TTL expires.
175
+ */
176
+ release(scopeKey: string, inputHash: string): Promise<void>;
177
+ gc(nowMs?: number): Promise<number>;
178
+ }
179
+ declare class InMemoryWorkspaceBridgeIdempotencyStore implements WorkspaceBridgeIdempotencyStore {
180
+ private readonly records;
181
+ private lastGcMs;
182
+ begin<TInput, TOutput>(options: BeginIdempotencyOptions<TInput>): Promise<IdempotencyBeginResult<TOutput>>;
183
+ complete<TOutput>(options: CompleteIdempotencyOptions<TOutput>): Promise<void>;
184
+ release(scopeKey: string, inputHash: string): Promise<void>;
185
+ gc(nowMs?: number): Promise<number>;
186
+ }
187
+ declare function runWithWorkspaceBridgeIdempotency<TInput, TOutput>(store: WorkspaceBridgeIdempotencyStore | undefined, options: BeginIdempotencyOptions<TInput>, execute: () => Promise<WorkspaceBridgeCallResponse<TOutput>>): Promise<WorkspaceBridgeCallResponse<TOutput>>;
188
+ declare function hashNormalizedInput(input: unknown): string;
189
+
190
+ declare const WORKSPACE_BRIDGE_TOKEN_AUDIENCE = "workspace-bridge";
191
+ declare const WORKSPACE_BRIDGE_REFRESH_TOKEN_AUDIENCE = "workspace-bridge-refresh";
192
+ declare const DEFAULT_WORKSPACE_BRIDGE_RUNTIME_TOKEN_TTL_MS: number;
193
+ declare const DEFAULT_WORKSPACE_BRIDGE_RUNTIME_REFRESH_TOKEN_TTL_MS: number;
194
+ declare const MAX_WORKSPACE_BRIDGE_RUNTIME_TOKEN_TTL_MS: number;
195
+ interface WorkspaceBridgeTokenClaimsBase {
196
+ aud: string;
197
+ workspaceId: string;
198
+ sessionId?: string;
199
+ runtimeId?: string;
200
+ capabilities: readonly string[];
201
+ iat: number;
202
+ exp: number;
203
+ jti: string;
204
+ tokenTtlMs?: number;
205
+ }
206
+ interface WorkspaceBridgeRuntimeTokenClaims extends WorkspaceBridgeTokenClaimsBase {
207
+ aud: typeof WORKSPACE_BRIDGE_TOKEN_AUDIENCE;
208
+ }
209
+ interface WorkspaceBridgeRuntimeRefreshTokenClaims extends WorkspaceBridgeTokenClaimsBase {
210
+ aud: typeof WORKSPACE_BRIDGE_REFRESH_TOKEN_AUDIENCE;
211
+ /** Short-lived call-token TTL to use when this refresh token re-mints. */
212
+ tokenTtlMs?: number;
213
+ }
214
+ interface MintWorkspaceBridgeRuntimeTokenOptions {
215
+ secret: string;
216
+ workspaceId: string;
217
+ sessionId?: string;
218
+ runtimeId?: string;
219
+ capabilities: readonly string[];
220
+ ttlMs?: number;
221
+ nowMs?: number;
222
+ jti?: string;
223
+ }
224
+ interface MintWorkspaceBridgeRuntimeRefreshTokenOptions extends MintWorkspaceBridgeRuntimeTokenOptions {
225
+ /** Short-lived call-token TTL to use when this refresh token re-mints. */
226
+ tokenTtlMs?: number;
227
+ }
228
+ interface VerifyWorkspaceBridgeRuntimeTokenOptions {
229
+ secret: string;
230
+ nowMs?: number;
231
+ requiredCapabilities?: readonly string[];
232
+ }
233
+ interface VerifyWorkspaceBridgeRuntimeRefreshTokenOptions {
234
+ secret: string;
235
+ nowMs?: number;
236
+ }
237
+ interface VerifiedWorkspaceBridgeRuntimeToken {
238
+ claims: WorkspaceBridgeRuntimeTokenClaims;
239
+ authContext: BridgeAuthContext;
240
+ }
241
+ interface VerifiedWorkspaceBridgeRuntimeRefreshToken {
242
+ claims: WorkspaceBridgeRuntimeRefreshTokenClaims;
243
+ }
244
+ declare function mintWorkspaceBridgeRuntimeToken(options: MintWorkspaceBridgeRuntimeTokenOptions): string;
245
+ declare function mintWorkspaceBridgeRuntimeRefreshToken(options: MintWorkspaceBridgeRuntimeRefreshTokenOptions): string;
246
+ declare function verifyWorkspaceBridgeRuntimeToken(token: string, options: VerifyWorkspaceBridgeRuntimeTokenOptions): VerifiedWorkspaceBridgeRuntimeToken;
247
+ declare function verifyWorkspaceBridgeRuntimeRefreshToken(token: string, options: VerifyWorkspaceBridgeRuntimeRefreshTokenOptions): VerifiedWorkspaceBridgeRuntimeRefreshToken;
248
+ declare function clampWorkspaceBridgeRuntimeTokenTtlMs(ttlMs: number | undefined): number | undefined;
249
+ declare function runtimeClaimsToBridgeAuthContext(claims: WorkspaceBridgeRuntimeTokenClaims): BridgeAuthContext;
250
+
251
+ interface WorkspaceBridgeRuntimeRefreshTokenUseOptions {
252
+ jti: string;
253
+ nowMs?: number;
254
+ windowMs: number;
255
+ maxUses: number;
256
+ /** Expiry time for the refresh token that owns this jti. Used for bounded in-memory GC. */
257
+ expiresAtMs?: number;
258
+ }
259
+ type WorkspaceBridgeRuntimeRefreshTokenUseResult = {
260
+ allowed: true;
261
+ } | {
262
+ allowed: false;
263
+ reason: "revoked";
264
+ } | {
265
+ allowed: false;
266
+ reason: "rate-limited";
267
+ retryAfterMs: number;
268
+ };
269
+ interface WorkspaceBridgeRuntimeRefreshTokenStore {
270
+ revoke(jti: string, expiresAtMs?: number): void | Promise<void>;
271
+ recordUse(options: WorkspaceBridgeRuntimeRefreshTokenUseOptions): WorkspaceBridgeRuntimeRefreshTokenUseResult | Promise<WorkspaceBridgeRuntimeRefreshTokenUseResult>;
272
+ }
273
+ declare class InMemoryWorkspaceBridgeRuntimeRefreshTokenStore implements WorkspaceBridgeRuntimeRefreshTokenStore {
274
+ private readonly revoked;
275
+ private readonly rateLimits;
276
+ private lastGcMs;
277
+ revoke(jti: string, expiresAtMs?: number): void;
278
+ recordUse(options: WorkspaceBridgeRuntimeRefreshTokenUseOptions): WorkspaceBridgeRuntimeRefreshTokenUseResult;
279
+ gc(nowMs?: number): number;
280
+ }
281
+
282
+ interface WorkspaceBridgeHttpRoutesOptions {
283
+ registry?: WorkspaceBridgeRegistry;
284
+ getRegistry?: (request: FastifyRequest, body: WorkspaceBridgeCallRequest) => WorkspaceBridgeRegistry | Promise<WorkspaceBridgeRegistry>;
285
+ browserAuthPolicy?: BridgeAuthPolicy;
286
+ runtimeTokenSecret?: string;
287
+ runtimeRefreshTokenSecret?: string;
288
+ runtimeRefreshTokenStore?: WorkspaceBridgeRuntimeRefreshTokenStore;
289
+ getRuntimeRefreshTokenStore?: (request: FastifyRequest, claims: WorkspaceBridgeRuntimeRefreshTokenClaims) => WorkspaceBridgeRuntimeRefreshTokenStore | undefined | Promise<WorkspaceBridgeRuntimeRefreshTokenStore | undefined>;
290
+ refreshTokenRateLimit?: {
291
+ maxUses?: number;
292
+ windowMs?: number;
293
+ };
294
+ ownerWorkspaceId?: string;
295
+ getOwnerWorkspaceId?: (request: FastifyRequest, body: WorkspaceBridgeCallRequest, auth: BridgeAuthContext) => string | undefined | Promise<string | undefined>;
296
+ idempotencyStore?: WorkspaceBridgeIdempotencyStore;
297
+ getIdempotencyStore?: (request: FastifyRequest, body: WorkspaceBridgeCallRequest) => WorkspaceBridgeIdempotencyStore | undefined | Promise<WorkspaceBridgeIdempotencyStore | undefined>;
298
+ maxBodyBytes?: number;
299
+ }
300
+ declare function workspaceBridgeHttpRoutes(app: FastifyInstance, opts: WorkspaceBridgeHttpRoutesOptions, done: (err?: Error) => void): void;
301
+
302
+ interface TrustedDomainBridgeHandlerPolicy {
303
+ /** Default true. Trusted app/domain ops should be versioned: domain.v1.action. */
304
+ requireVersionedOp?: boolean;
305
+ /** Default rejects generic workspace file proxy surfaces. */
306
+ reservedOpPrefixes?: readonly string[];
307
+ }
308
+ interface TrustedDomainBridgeHandlerOptions<TInput = unknown, TOutput = unknown> {
309
+ op: string;
310
+ version: number;
311
+ owner: string;
312
+ callerClassesAllowed: readonly BridgeCallerClass[];
313
+ requiredCapabilities: readonly string[];
314
+ inputSchema: unknown;
315
+ outputSchema?: unknown;
316
+ timeoutMs?: number;
317
+ maxInputBytes?: number;
318
+ maxOutputBytes: number;
319
+ idempotencyPolicy?: BridgeIdempotencyPolicy;
320
+ handler: WorkspaceBridgeHandler<TInput, TOutput>;
321
+ policy?: TrustedDomainBridgeHandlerPolicy;
322
+ }
323
+ interface TrustedDomainBridgeHandlerRegistration<TInput = unknown, TOutput = unknown> {
324
+ definition: WorkspaceBridgeOperationDefinition<TInput, TOutput>;
325
+ handler: WorkspaceBridgeHandler<TInput, TOutput>;
326
+ }
327
+ /**
328
+ * Trusted-only helper for app/core/domain-owned WorkspaceBridge handlers.
329
+ *
330
+ * This is intentionally NOT a generated-plugin host-process handler API:
331
+ * generated/runtime plugins must keep using sandbox/runtime SDK calls and must
332
+ * not self-register arbitrary host handlers or Fastify routes.
333
+ */
334
+ declare function defineTrustedDomainBridgeHandler<TInput = unknown, TOutput = unknown>(options: TrustedDomainBridgeHandlerOptions<TInput, TOutput>): TrustedDomainBridgeHandlerRegistration<TInput, TOutput>;
335
+
336
+ interface WorkspaceBridgeRuntimeCoreOptions {
337
+ /** Reuse an existing registry; otherwise a fresh in-memory one is created. */
338
+ registry?: WorkspaceBridgeRegistry;
339
+ /** Host/app/internal plugin bridge handlers to register at boot. */
340
+ handlers?: ReadonlyArray<{
341
+ definition: WorkspaceBridgeOperationDefinition;
342
+ handler: WorkspaceBridgeHandler;
343
+ }>;
344
+ /** Workspace that owns a newly-created registry. Ignored when registry is provided. */
345
+ ownerWorkspaceId?: string;
346
+ }
347
+ interface WorkspaceBridgeRuntimeCore {
348
+ registry: WorkspaceBridgeRegistry;
349
+ }
350
+ /**
351
+ * Shared bridge bootstrap: build/accept a registry and register host-supplied
352
+ * bridge handlers. Domain handlers belong to the app/internal plugin that owns
353
+ * the domain; workspace only owns the generic registry/runtime composition.
354
+ */
355
+ declare function createWorkspaceBridgeRuntimeCore(options?: WorkspaceBridgeRuntimeCoreOptions): WorkspaceBridgeRuntimeCore;
128
356
 
129
357
  /**
130
358
  * boring-ui system prompt — workflow steps + a Pi-style docs pointer
@@ -392,4 +620,4 @@ interface RuntimeBackendGatewayOptions {
392
620
  }
393
621
  declare function runtimeBackendGateway(app: FastifyInstance, opts: RuntimeBackendGatewayOptions): Promise<void>;
394
622
 
395
- export { BoringPluginAssetManager, BoringPluginEvent, BoringPluginFrontTarget, BoringPluginFrontTargetResolver, BoringPluginListEntry, type BoringPluginScanResult, BoringPluginSource, BoringPluginSourceInput, BoringServerPluginManifest, type PluginRestartWarning, type RuntimeBackendDiagnostic, type RuntimeBackendDispatchRequest, type RuntimeBackendDispatchResponse, type RuntimeBackendDispatcher, RuntimeBackendError, type RuntimeBackendGatewayOptions, RuntimeBackendRegistry, type RuntimeBackendReloadResult, UiBridge, type UiRoutesOptions, WorkspaceServerPluginAsset, aggregatePluginPrompts, boringPluginRoutes, buildBoringSystemPrompt, collectRestartWarnings, createExecUiTool, createGetUiStateTool, createWorkspaceUiTools, definePluginAsset, pluginFileSignature, preflightBoringPlugins, readBoringPlugins, readPluginSignatureCache, resolvePluginAssetPath, runtimeBackendGateway, scanBoringPlugins, uiRoutes, writePluginSignatureCache };
623
+ export { type BeginIdempotencyOptions, BoringPluginAssetManager, BoringPluginEvent, BoringPluginFrontTarget, BoringPluginFrontTargetResolver, BoringPluginListEntry, type BoringPluginScanResult, BoringPluginSource, BoringPluginSourceInput, BoringServerPluginManifest, BridgeAuthContext, BridgeAuthPolicy, BridgeCallerClass, BridgeIdempotencyPolicy, type CompleteIdempotencyOptions, DEFAULT_WORKSPACE_BRIDGE_RUNTIME_REFRESH_TOKEN_TTL_MS, DEFAULT_WORKSPACE_BRIDGE_RUNTIME_TOKEN_TTL_MS, type IdempotencyBeginResult, type IdempotencyRecordStatus, InMemoryWorkspaceBridgeIdempotencyStore, InMemoryWorkspaceBridgeRuntimeRefreshTokenStore, MAX_WORKSPACE_BRIDGE_RUNTIME_TOKEN_TTL_MS, type MintWorkspaceBridgeRuntimeRefreshTokenOptions, type MintWorkspaceBridgeRuntimeTokenOptions, type PluginRestartWarning, type RuntimeBackendDiagnostic, type RuntimeBackendDispatchRequest, type RuntimeBackendDispatchResponse, type RuntimeBackendDispatcher, RuntimeBackendError, type RuntimeBackendGatewayOptions, RuntimeBackendRegistry, type RuntimeBackendReloadResult, type TrustedDomainBridgeHandlerOptions, type TrustedDomainBridgeHandlerPolicy, type TrustedDomainBridgeHandlerRegistration, UiBridge, type UiRoutesOptions, type VerifiedWorkspaceBridgeRuntimeRefreshToken, type VerifiedWorkspaceBridgeRuntimeToken, type VerifyWorkspaceBridgeRuntimeRefreshTokenOptions, type VerifyWorkspaceBridgeRuntimeTokenOptions, WORKSPACE_BRIDGE_REFRESH_TOKEN_AUDIENCE, WORKSPACE_BRIDGE_TOKEN_AUDIENCE, WorkspaceBridge, WorkspaceBridgeCallRequest, WorkspaceBridgeCallResponse, WorkspaceBridgeError, WorkspaceBridgeHandler, type WorkspaceBridgeHttpRoutesOptions, type WorkspaceBridgeIdempotencyRecord, type WorkspaceBridgeIdempotencyStore, WorkspaceBridgeOperationDefinition, WorkspaceBridgeRegistry, type WorkspaceBridgeRuntimeCore, type WorkspaceBridgeRuntimeCoreOptions, type WorkspaceBridgeRuntimeRefreshTokenClaims, type WorkspaceBridgeRuntimeRefreshTokenStore, type WorkspaceBridgeRuntimeRefreshTokenUseOptions, type WorkspaceBridgeRuntimeRefreshTokenUseResult, type WorkspaceBridgeRuntimeTokenClaims, WorkspaceServerPluginAsset, aggregatePluginPrompts, boringPluginRoutes, buildBoringSystemPrompt, clampWorkspaceBridgeRuntimeTokenTtlMs, collectRestartWarnings, createExecUiTool, createGetUiStateTool, createWorkspaceBridgeRuntimeCore, createWorkspaceUiTools, definePluginAsset, defineTrustedDomainBridgeHandler, hashNormalizedInput, mintWorkspaceBridgeRuntimeRefreshToken, mintWorkspaceBridgeRuntimeToken, pluginFileSignature, preflightBoringPlugins, readBoringPlugins, readPluginSignatureCache, resolvePluginAssetPath, runWithWorkspaceBridgeIdempotency, runtimeBackendGateway, runtimeClaimsToBridgeAuthContext, scanBoringPlugins, stableStringify, uiRoutes, verifyWorkspaceBridgeRuntimeRefreshToken, verifyWorkspaceBridgeRuntimeToken, workspaceBridgeHttpRoutes, writePluginSignatureCache };