@hachej/boring-workspace 0.1.82 → 0.1.84

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/dist/app-front.js CHANGED
@@ -1,6 +1,6 @@
1
- import { B as e, C as t, E as n, F as r, G as i, H as a, I as o, Kt as s, L as c, Lt as l, M as u, N as d, P as f, Q as p, R as m, Rt as h, S as g, Sn as _, T as ee, V as v, an as te, c as ne, cn as re, g as ie, hn as ae, j as oe, kt as se, m as ce, mn as le, n as ue, on as de, r as fe, x as pe, xn as me, z as he } from "./WorkspaceProvider-DH-yiJZ8.js";
1
+ import { B as e, C as t, E as n, F as r, G as i, H as a, I as o, Kt as s, L as c, Lt as l, M as u, N as d, P as f, Q as p, R as m, Rt as h, S as g, Sn as _, T as ee, V as v, an as te, c as ne, cn as re, g as ie, hn as ae, j as oe, kt as se, m as ce, mn as le, n as ue, on as de, r as fe, x as pe, xn as me, z as he } from "./WorkspaceProvider-C8rWNm72.js";
2
2
  import { t as y } from "./utils-BRcxFdrz.js";
3
- import { a as ge, c as _e, f as ve, l as ye, n as be, o as xe, r as Se, s as Ce, t as we, u as Te } from "./WorkspaceLoadingState-D_b8t-6U.js";
3
+ import { a as ge, c as _e, f as ve, l as ye, n as be, o as xe, r as Se, s as Ce, t as we, u as Te } from "./WorkspaceLoadingState-BkAUFt_A.js";
4
4
  import { createElement as Ee, useCallback as b, useEffect as x, useLayoutEffect as De, useMemo as S, useRef as C, useState as w, useSyncExternalStore as Oe } from "react";
5
5
  import { Fragment as T, jsx as E, jsxs as D } from "react/jsx-runtime";
6
6
  import { ChevronRight as ke, Clock3 as Ae, ExternalLink as je, FileText as Me, Maximize2 as Ne, MessageSquare as Pe, MessageSquarePlus as O, Moon as Fe, MoreHorizontal as Ie, PanelLeftClose as Le, PanelLeftOpen as Re, Pin as ze, PinOff as Be, Plug as Ve, Plus as He, RefreshCw as Ue, Search as We, Settings as Ge, Sparkles as Ke, Sun as qe, X as Je } from "lucide-react";
@@ -3330,20 +3330,28 @@ function mintWorkspaceBridgeRuntimeRefreshToken(options) {
3330
3330
  });
3331
3331
  }
3332
3332
  function verifyWorkspaceBridgeRuntimeToken(token, options) {
3333
+ return authorizeWorkspaceBridgeRuntimeToken(
3334
+ verifyWorkspaceBridgeRuntimeTokenClaims(token, options),
3335
+ options.requiredCapabilities
3336
+ );
3337
+ }
3338
+ function verifyWorkspaceBridgeRuntimeTokenClaims(token, options) {
3333
3339
  assertUsableSecret(options.secret);
3334
3340
  const claims = parseAndVerifyToken(token, options.secret);
3335
3341
  const now = Math.floor((options.nowMs ?? Date.now()) / 1e3);
3336
3342
  ensureLiveTokenClaims(claims, now, WORKSPACE_BRIDGE_TOKEN_AUDIENCE, "Runtime bridge token");
3337
- const missingCapability = (options.requiredCapabilities ?? []).find(
3338
- (capability) => !claims.capabilities.includes(capability)
3343
+ return { claims };
3344
+ }
3345
+ function authorizeWorkspaceBridgeRuntimeToken(verified, requiredCapabilities = []) {
3346
+ const missingCapability = requiredCapabilities.find(
3347
+ (capability) => !verified.claims.capabilities.includes(capability)
3339
3348
  );
3340
3349
  if (missingCapability) {
3341
3350
  throw bridgeTokenError("BRIDGE_CAPABILITY_DENIED" /* CapabilityDenied */, "Runtime bridge token is missing a required capability");
3342
3351
  }
3343
- const runtimeClaims = claims;
3344
3352
  return {
3345
- claims: runtimeClaims,
3346
- authContext: runtimeClaimsToBridgeAuthContext(runtimeClaims)
3353
+ claims: verified.claims,
3354
+ authContext: runtimeClaimsToBridgeAuthContext(verified.claims)
3347
3355
  };
3348
3356
  }
3349
3357
  function verifyWorkspaceBridgeRuntimeRefreshToken(token, options) {
@@ -3565,21 +3573,42 @@ function workspaceBridgeHttpRoutes(app, opts, done) {
3565
3573
  return sendBridgeError(reply, 400, void 0, "BRIDGE_SCHEMA_INVALID" /* SchemaInvalid */, "WorkspaceBridge request body is invalid");
3566
3574
  }
3567
3575
  const body = { ...parsed.data, input: parsed.data.input ?? {} };
3576
+ const authHeader = firstHeader(request.headers.authorization);
3577
+ const runtimeToken = authHeader?.startsWith("Bearer ") ? authHeader.slice("Bearer ".length) : void 0;
3578
+ let verifiedRuntimeToken;
3579
+ if (runtimeToken !== void 0 && opts.assertRuntimeWorkspaceScope) {
3580
+ try {
3581
+ verifiedRuntimeToken = resolveRuntimeClaims(runtimeToken, opts);
3582
+ } catch (err) {
3583
+ const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_HANDLER_FAILED" /* HandlerFailed */, "WorkspaceBridge transport failed");
3584
+ return sendBridgeError(reply, statusForBridgeError(bridgeError.code), body.requestId, bridgeError.code, bridgeError.message);
3585
+ }
3586
+ await opts.assertRuntimeWorkspaceScope(request, verifiedRuntimeToken.claims);
3587
+ }
3588
+ let authorized;
3568
3589
  try {
3569
3590
  const registry = await resolveRegistry(request, body, opts);
3570
3591
  const definition = registry.getDefinition(body.op);
3571
3592
  if (!definition) {
3572
3593
  return sendBridgeError(reply, statusForBridgeError("BRIDGE_OP_NOT_FOUND" /* OpNotFound */), body.requestId, "BRIDGE_OP_NOT_FOUND" /* OpNotFound */, "WorkspaceBridge operation is not registered");
3573
3594
  }
3574
- const authHeader = firstHeader(request.headers.authorization);
3575
- const authContext = authHeader?.startsWith("Bearer ") ? resolveRuntimeContext(authHeader.slice("Bearer ".length), opts, definition) : await resolveBrowserContext(request, opts, definition, body);
3595
+ const authContext = runtimeToken !== void 0 ? resolveRuntimeContext(runtimeToken, opts, definition, verifiedRuntimeToken) : await resolveBrowserContext(request, opts, definition, body);
3596
+ authorized = { registry, definition, authContext };
3597
+ } catch (err) {
3598
+ const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_HANDLER_FAILED" /* HandlerFailed */, "WorkspaceBridge transport failed");
3599
+ return sendBridgeError(reply, statusForBridgeError(bridgeError.code), body.requestId, bridgeError.code, bridgeError.message);
3600
+ }
3601
+ if (runtimeToken !== void 0 && opts.admitRuntimeOperation) {
3602
+ await opts.admitRuntimeOperation(authorized.authContext.workspaceId);
3603
+ }
3604
+ try {
3576
3605
  const idempotencyStore = opts.getIdempotencyStore ? await opts.getIdempotencyStore(request, body) : opts.idempotencyStore;
3577
- const expectedWorkspaceId = opts.getOwnerWorkspaceId ? await opts.getOwnerWorkspaceId(request, body, authContext) : opts.ownerWorkspaceId;
3606
+ const expectedWorkspaceId = opts.getOwnerWorkspaceId ? await opts.getOwnerWorkspaceId(request, body, authorized.authContext) : opts.ownerWorkspaceId;
3578
3607
  const response = await runWithWorkspaceBridgeIdempotency(idempotencyStore, {
3579
- definition,
3608
+ definition: authorized.definition,
3580
3609
  request: body,
3581
- auth: authContext
3582
- }, async () => await registry.call(body, authContext, { expectedWorkspaceId }));
3610
+ auth: authorized.authContext
3611
+ }, async () => await authorized.registry.call(body, authorized.authContext, { expectedWorkspaceId }));
3583
3612
  return await sendResponse(reply, response);
3584
3613
  } catch (err) {
3585
3614
  const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_HANDLER_FAILED" /* HandlerFailed */, "WorkspaceBridge transport failed");
@@ -3595,12 +3624,21 @@ function workspaceBridgeHttpRoutes(app, opts, done) {
3595
3624
  if (!opts.runtimeTokenSecret || !opts.runtimeRefreshTokenSecret) {
3596
3625
  return sendBridgeError(reply, 401, void 0, "BRIDGE_AUTH_REQUIRED" /* AuthRequired */, "WorkspaceBridge token refresh is not configured");
3597
3626
  }
3627
+ const nowMs = Date.now();
3628
+ let verified;
3598
3629
  try {
3599
- const nowMs = Date.now();
3600
- const verified = verifyWorkspaceBridgeRuntimeRefreshToken(authHeader.slice("Bearer ".length), {
3630
+ verified = verifyWorkspaceBridgeRuntimeRefreshToken(authHeader.slice("Bearer ".length), {
3601
3631
  secret: opts.runtimeRefreshTokenSecret,
3602
3632
  nowMs
3603
3633
  });
3634
+ } catch (err) {
3635
+ const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_INVALID_TOKEN" /* InvalidToken */, "WorkspaceBridge refresh token is invalid");
3636
+ return sendBridgeError(reply, statusForBridgeError(bridgeError.code), void 0, bridgeError.code, bridgeError.message);
3637
+ }
3638
+ if (opts.assertRuntimeWorkspaceScope) {
3639
+ await opts.assertRuntimeWorkspaceScope(request, verified.claims);
3640
+ }
3641
+ try {
3604
3642
  const store = opts.getRuntimeRefreshTokenStore ? await opts.getRuntimeRefreshTokenStore(request, verified.claims) ?? defaultRefreshTokenStore : defaultRefreshTokenStore;
3605
3643
  const refreshUse = await store.recordUse({
3606
3644
  jti: verified.claims.jti,
@@ -3643,14 +3681,29 @@ async function resolveRegistry(request, body, opts) {
3643
3681
  }
3644
3682
  return registry;
3645
3683
  }
3646
- function resolveRuntimeContext(token, opts, definition) {
3684
+ function resolveRuntimeContext(token, opts, definition, verified) {
3685
+ let authorized;
3686
+ if (verified) {
3687
+ authorized = authorizeWorkspaceBridgeRuntimeToken(verified, definition.requiredCapabilities);
3688
+ } else {
3689
+ if (!opts.runtimeTokenSecret) {
3690
+ throw createWorkspaceBridgeError("BRIDGE_AUTH_REQUIRED" /* AuthRequired */, "Runtime bridge token auth is not configured");
3691
+ }
3692
+ authorized = verifyWorkspaceBridgeRuntimeToken(token, {
3693
+ secret: opts.runtimeTokenSecret,
3694
+ requiredCapabilities: definition.requiredCapabilities
3695
+ });
3696
+ }
3697
+ if (opts.admitRuntimeOperation && !definition.callerClassesAllowed.includes("runtime")) {
3698
+ throw createWorkspaceBridgeError("BRIDGE_CALLER_NOT_ALLOWED" /* CallerNotAllowed */, "Caller class is not allowed for operation");
3699
+ }
3700
+ return authorized.authContext;
3701
+ }
3702
+ function resolveRuntimeClaims(token, opts) {
3647
3703
  if (!opts.runtimeTokenSecret) {
3648
3704
  throw createWorkspaceBridgeError("BRIDGE_AUTH_REQUIRED" /* AuthRequired */, "Runtime bridge token auth is not configured");
3649
3705
  }
3650
- return verifyWorkspaceBridgeRuntimeToken(token, {
3651
- secret: opts.runtimeTokenSecret,
3652
- requiredCapabilities: definition.requiredCapabilities
3653
- }).authContext;
3706
+ return verifyWorkspaceBridgeRuntimeTokenClaims(token, { secret: opts.runtimeTokenSecret });
3654
3707
  }
3655
3708
  async function resolveBrowserContext(request, opts, definition, body) {
3656
3709
  if (!opts.browserAuthPolicy) {
package/dist/server.d.ts CHANGED
@@ -232,6 +232,7 @@ interface VerifyWorkspaceBridgeRuntimeTokenOptions {
232
232
  nowMs?: number;
233
233
  requiredCapabilities?: readonly string[];
234
234
  }
235
+ type VerifyWorkspaceBridgeRuntimeTokenClaimsOptions = Omit<VerifyWorkspaceBridgeRuntimeTokenOptions, "requiredCapabilities">;
235
236
  interface VerifyWorkspaceBridgeRuntimeRefreshTokenOptions {
236
237
  secret: string;
237
238
  nowMs?: number;
@@ -240,12 +241,17 @@ interface VerifiedWorkspaceBridgeRuntimeToken {
240
241
  claims: WorkspaceBridgeRuntimeTokenClaims;
241
242
  authContext: BridgeAuthContext;
242
243
  }
244
+ interface VerifiedWorkspaceBridgeRuntimeTokenClaims {
245
+ claims: WorkspaceBridgeRuntimeTokenClaims;
246
+ }
243
247
  interface VerifiedWorkspaceBridgeRuntimeRefreshToken {
244
248
  claims: WorkspaceBridgeRuntimeRefreshTokenClaims;
245
249
  }
246
250
  declare function mintWorkspaceBridgeRuntimeToken(options: MintWorkspaceBridgeRuntimeTokenOptions): string;
247
251
  declare function mintWorkspaceBridgeRuntimeRefreshToken(options: MintWorkspaceBridgeRuntimeRefreshTokenOptions): string;
248
252
  declare function verifyWorkspaceBridgeRuntimeToken(token: string, options: VerifyWorkspaceBridgeRuntimeTokenOptions): VerifiedWorkspaceBridgeRuntimeToken;
253
+ declare function verifyWorkspaceBridgeRuntimeTokenClaims(token: string, options: VerifyWorkspaceBridgeRuntimeTokenClaimsOptions): VerifiedWorkspaceBridgeRuntimeTokenClaims;
254
+ declare function authorizeWorkspaceBridgeRuntimeToken(verified: VerifiedWorkspaceBridgeRuntimeTokenClaims, requiredCapabilities?: readonly string[]): VerifiedWorkspaceBridgeRuntimeToken;
249
255
  declare function verifyWorkspaceBridgeRuntimeRefreshToken(token: string, options: VerifyWorkspaceBridgeRuntimeRefreshTokenOptions): VerifiedWorkspaceBridgeRuntimeRefreshToken;
250
256
  declare function clampWorkspaceBridgeRuntimeTokenTtlMs(ttlMs: number | undefined): number | undefined;
251
257
  declare function runtimeClaimsToBridgeAuthContext(claims: WorkspaceBridgeRuntimeTokenClaims): BridgeAuthContext;
@@ -289,6 +295,8 @@ interface WorkspaceBridgeHttpRoutesOptions {
289
295
  runtimeRefreshTokenSecret?: string;
290
296
  runtimeRefreshTokenStore?: WorkspaceBridgeRuntimeRefreshTokenStore;
291
297
  getRuntimeRefreshTokenStore?: (request: FastifyRequest, claims: WorkspaceBridgeRuntimeRefreshTokenClaims) => WorkspaceBridgeRuntimeRefreshTokenStore | undefined | Promise<WorkspaceBridgeRuntimeRefreshTokenStore | undefined>;
298
+ assertRuntimeWorkspaceScope?: (request: FastifyRequest, claims: WorkspaceBridgeRuntimeTokenClaims | WorkspaceBridgeRuntimeRefreshTokenClaims) => void | Promise<void>;
299
+ admitRuntimeOperation?: (workspaceId: string) => void | Promise<void>;
292
300
  refreshTokenRateLimit?: {
293
301
  maxUses?: number;
294
302
  windowMs?: number;
@@ -622,4 +630,4 @@ interface RuntimeBackendGatewayOptions {
622
630
  }
623
631
  declare function runtimeBackendGateway(app: FastifyInstance, opts: RuntimeBackendGatewayOptions): Promise<void>;
624
632
 
625
- 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 };
633
+ 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 VerifiedWorkspaceBridgeRuntimeTokenClaims, type VerifyWorkspaceBridgeRuntimeRefreshTokenOptions, type VerifyWorkspaceBridgeRuntimeTokenClaimsOptions, 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, authorizeWorkspaceBridgeRuntimeToken, 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, verifyWorkspaceBridgeRuntimeTokenClaims, workspaceBridgeHttpRoutes, writePluginSignatureCache };
package/dist/server.js CHANGED
@@ -1409,20 +1409,28 @@ function mintWorkspaceBridgeRuntimeRefreshToken(options) {
1409
1409
  });
1410
1410
  }
1411
1411
  function verifyWorkspaceBridgeRuntimeToken(token, options) {
1412
+ return authorizeWorkspaceBridgeRuntimeToken(
1413
+ verifyWorkspaceBridgeRuntimeTokenClaims(token, options),
1414
+ options.requiredCapabilities
1415
+ );
1416
+ }
1417
+ function verifyWorkspaceBridgeRuntimeTokenClaims(token, options) {
1412
1418
  assertUsableSecret(options.secret);
1413
1419
  const claims = parseAndVerifyToken(token, options.secret);
1414
1420
  const now = Math.floor((options.nowMs ?? Date.now()) / 1e3);
1415
1421
  ensureLiveTokenClaims(claims, now, WORKSPACE_BRIDGE_TOKEN_AUDIENCE, "Runtime bridge token");
1416
- const missingCapability = (options.requiredCapabilities ?? []).find(
1417
- (capability) => !claims.capabilities.includes(capability)
1422
+ return { claims };
1423
+ }
1424
+ function authorizeWorkspaceBridgeRuntimeToken(verified, requiredCapabilities = []) {
1425
+ const missingCapability = requiredCapabilities.find(
1426
+ (capability) => !verified.claims.capabilities.includes(capability)
1418
1427
  );
1419
1428
  if (missingCapability) {
1420
1429
  throw bridgeTokenError("BRIDGE_CAPABILITY_DENIED" /* CapabilityDenied */, "Runtime bridge token is missing a required capability");
1421
1430
  }
1422
- const runtimeClaims = claims;
1423
1431
  return {
1424
- claims: runtimeClaims,
1425
- authContext: runtimeClaimsToBridgeAuthContext(runtimeClaims)
1432
+ claims: verified.claims,
1433
+ authContext: runtimeClaimsToBridgeAuthContext(verified.claims)
1426
1434
  };
1427
1435
  }
1428
1436
  function verifyWorkspaceBridgeRuntimeRefreshToken(token, options) {
@@ -1644,21 +1652,42 @@ function workspaceBridgeHttpRoutes(app, opts, done) {
1644
1652
  return sendBridgeError(reply, 400, void 0, "BRIDGE_SCHEMA_INVALID" /* SchemaInvalid */, "WorkspaceBridge request body is invalid");
1645
1653
  }
1646
1654
  const body = { ...parsed.data, input: parsed.data.input ?? {} };
1655
+ const authHeader = firstHeader2(request.headers.authorization);
1656
+ const runtimeToken = authHeader?.startsWith("Bearer ") ? authHeader.slice("Bearer ".length) : void 0;
1657
+ let verifiedRuntimeToken;
1658
+ if (runtimeToken !== void 0 && opts.assertRuntimeWorkspaceScope) {
1659
+ try {
1660
+ verifiedRuntimeToken = resolveRuntimeClaims(runtimeToken, opts);
1661
+ } catch (err) {
1662
+ const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_HANDLER_FAILED" /* HandlerFailed */, "WorkspaceBridge transport failed");
1663
+ return sendBridgeError(reply, statusForBridgeError(bridgeError.code), body.requestId, bridgeError.code, bridgeError.message);
1664
+ }
1665
+ await opts.assertRuntimeWorkspaceScope(request, verifiedRuntimeToken.claims);
1666
+ }
1667
+ let authorized;
1647
1668
  try {
1648
1669
  const registry = await resolveRegistry(request, body, opts);
1649
1670
  const definition = registry.getDefinition(body.op);
1650
1671
  if (!definition) {
1651
1672
  return sendBridgeError(reply, statusForBridgeError("BRIDGE_OP_NOT_FOUND" /* OpNotFound */), body.requestId, "BRIDGE_OP_NOT_FOUND" /* OpNotFound */, "WorkspaceBridge operation is not registered");
1652
1673
  }
1653
- const authHeader = firstHeader2(request.headers.authorization);
1654
- const authContext = authHeader?.startsWith("Bearer ") ? resolveRuntimeContext(authHeader.slice("Bearer ".length), opts, definition) : await resolveBrowserContext(request, opts, definition, body);
1674
+ const authContext = runtimeToken !== void 0 ? resolveRuntimeContext(runtimeToken, opts, definition, verifiedRuntimeToken) : await resolveBrowserContext(request, opts, definition, body);
1675
+ authorized = { registry, definition, authContext };
1676
+ } catch (err) {
1677
+ const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_HANDLER_FAILED" /* HandlerFailed */, "WorkspaceBridge transport failed");
1678
+ return sendBridgeError(reply, statusForBridgeError(bridgeError.code), body.requestId, bridgeError.code, bridgeError.message);
1679
+ }
1680
+ if (runtimeToken !== void 0 && opts.admitRuntimeOperation) {
1681
+ await opts.admitRuntimeOperation(authorized.authContext.workspaceId);
1682
+ }
1683
+ try {
1655
1684
  const idempotencyStore = opts.getIdempotencyStore ? await opts.getIdempotencyStore(request, body) : opts.idempotencyStore;
1656
- const expectedWorkspaceId = opts.getOwnerWorkspaceId ? await opts.getOwnerWorkspaceId(request, body, authContext) : opts.ownerWorkspaceId;
1685
+ const expectedWorkspaceId = opts.getOwnerWorkspaceId ? await opts.getOwnerWorkspaceId(request, body, authorized.authContext) : opts.ownerWorkspaceId;
1657
1686
  const response = await runWithWorkspaceBridgeIdempotency(idempotencyStore, {
1658
- definition,
1687
+ definition: authorized.definition,
1659
1688
  request: body,
1660
- auth: authContext
1661
- }, async () => await registry.call(body, authContext, { expectedWorkspaceId }));
1689
+ auth: authorized.authContext
1690
+ }, async () => await authorized.registry.call(body, authorized.authContext, { expectedWorkspaceId }));
1662
1691
  return await sendResponse(reply, response);
1663
1692
  } catch (err) {
1664
1693
  const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_HANDLER_FAILED" /* HandlerFailed */, "WorkspaceBridge transport failed");
@@ -1674,12 +1703,21 @@ function workspaceBridgeHttpRoutes(app, opts, done) {
1674
1703
  if (!opts.runtimeTokenSecret || !opts.runtimeRefreshTokenSecret) {
1675
1704
  return sendBridgeError(reply, 401, void 0, "BRIDGE_AUTH_REQUIRED" /* AuthRequired */, "WorkspaceBridge token refresh is not configured");
1676
1705
  }
1706
+ const nowMs = Date.now();
1707
+ let verified;
1677
1708
  try {
1678
- const nowMs = Date.now();
1679
- const verified = verifyWorkspaceBridgeRuntimeRefreshToken(authHeader.slice("Bearer ".length), {
1709
+ verified = verifyWorkspaceBridgeRuntimeRefreshToken(authHeader.slice("Bearer ".length), {
1680
1710
  secret: opts.runtimeRefreshTokenSecret,
1681
1711
  nowMs
1682
1712
  });
1713
+ } catch (err) {
1714
+ const bridgeError = isBridgeError(err) ? err : createWorkspaceBridgeError("BRIDGE_INVALID_TOKEN" /* InvalidToken */, "WorkspaceBridge refresh token is invalid");
1715
+ return sendBridgeError(reply, statusForBridgeError(bridgeError.code), void 0, bridgeError.code, bridgeError.message);
1716
+ }
1717
+ if (opts.assertRuntimeWorkspaceScope) {
1718
+ await opts.assertRuntimeWorkspaceScope(request, verified.claims);
1719
+ }
1720
+ try {
1683
1721
  const store = opts.getRuntimeRefreshTokenStore ? await opts.getRuntimeRefreshTokenStore(request, verified.claims) ?? defaultRefreshTokenStore : defaultRefreshTokenStore;
1684
1722
  const refreshUse = await store.recordUse({
1685
1723
  jti: verified.claims.jti,
@@ -1722,14 +1760,29 @@ async function resolveRegistry(request, body, opts) {
1722
1760
  }
1723
1761
  return registry;
1724
1762
  }
1725
- function resolveRuntimeContext(token, opts, definition) {
1763
+ function resolveRuntimeContext(token, opts, definition, verified) {
1764
+ let authorized;
1765
+ if (verified) {
1766
+ authorized = authorizeWorkspaceBridgeRuntimeToken(verified, definition.requiredCapabilities);
1767
+ } else {
1768
+ if (!opts.runtimeTokenSecret) {
1769
+ throw createWorkspaceBridgeError("BRIDGE_AUTH_REQUIRED" /* AuthRequired */, "Runtime bridge token auth is not configured");
1770
+ }
1771
+ authorized = verifyWorkspaceBridgeRuntimeToken(token, {
1772
+ secret: opts.runtimeTokenSecret,
1773
+ requiredCapabilities: definition.requiredCapabilities
1774
+ });
1775
+ }
1776
+ if (opts.admitRuntimeOperation && !definition.callerClassesAllowed.includes("runtime")) {
1777
+ throw createWorkspaceBridgeError("BRIDGE_CALLER_NOT_ALLOWED" /* CallerNotAllowed */, "Caller class is not allowed for operation");
1778
+ }
1779
+ return authorized.authContext;
1780
+ }
1781
+ function resolveRuntimeClaims(token, opts) {
1726
1782
  if (!opts.runtimeTokenSecret) {
1727
1783
  throw createWorkspaceBridgeError("BRIDGE_AUTH_REQUIRED" /* AuthRequired */, "Runtime bridge token auth is not configured");
1728
1784
  }
1729
- return verifyWorkspaceBridgeRuntimeToken(token, {
1730
- secret: opts.runtimeTokenSecret,
1731
- requiredCapabilities: definition.requiredCapabilities
1732
- }).authContext;
1785
+ return verifyWorkspaceBridgeRuntimeTokenClaims(token, { secret: opts.runtimeTokenSecret });
1733
1786
  }
1734
1787
  async function resolveBrowserContext(request, opts, definition, body) {
1735
1788
  if (!opts.browserAuthPolicy) {
@@ -3800,6 +3853,7 @@ export {
3800
3853
  WorkspaceBridgeErrorCode,
3801
3854
  WorkspaceBridgeRegistry,
3802
3855
  aggregatePluginPrompts,
3856
+ authorizeWorkspaceBridgeRuntimeToken,
3803
3857
  bootstrapServer,
3804
3858
  boringPluginRoutes,
3805
3859
  buildBoringSystemPrompt,
@@ -3840,6 +3894,7 @@ export {
3840
3894
  validateWorkspaceBridgeOperationDefinition,
3841
3895
  verifyWorkspaceBridgeRuntimeRefreshToken,
3842
3896
  verifyWorkspaceBridgeRuntimeToken,
3897
+ verifyWorkspaceBridgeRuntimeTokenClaims,
3843
3898
  workspaceBridgeHttpRoutes,
3844
3899
  writePluginSignatureCache
3845
3900
  };
@@ -3,6 +3,7 @@ import { FileTreeBridge } from '../../../../front/bridge/types';
3
3
  import { FilesystemId } from '../../../../shared/types/filesystem';
4
4
  import { PaneProps } from '../../../../shared/types/panel';
5
5
  import { LeftTabParams } from '../../../../shared/plugins/types';
6
+ import { ForwardRefExoticComponent, RefAttributes } from 'react';
6
7
  export { copyToClipboard } from './clipboard';
7
8
  export declare function preloadFileTreeComponent(): void;
8
9
  declare function clampContextMenuPosition(x: number, y: number, menuRect: Pick<DOMRect, "width" | "height">, viewportWidth: number, viewportHeight: number): {
@@ -30,6 +31,14 @@ export interface FileTreeViewProps {
30
31
  /** Forwarded to the inner <FileTree>. */
31
32
  className?: string;
32
33
  }
34
+ /** Imperative handle for hosts (e.g. `FileTreePane`'s refresh button) that need
35
+ * to force a re-sync of this root's listing on demand, outside the normal
36
+ * mutation/event-driven refresh paths. */
37
+ export interface FileTreeViewHandle {
38
+ /** Re-fetch this root's top-level listing plus every currently-expanded
39
+ * subfolder. Resolves once all of it has settled. */
40
+ refetch: () => Promise<void>;
41
+ }
33
42
  /**
34
43
  * File tree with the full workbench actions: tracks container height,
35
44
  * routes selects through `bridge.openFile`, and provides a right-click
@@ -41,7 +50,7 @@ export interface FileTreeViewProps {
41
50
  * want a "Files" panel; `WorkbenchLeftPane` uses this primitive directly to
42
51
  * share its search input with the Data tab.
43
52
  */
44
- export declare function FileTreeView({ rootDir, searchQuery, bridge, revealFileTreeRequest, filesystem, access, ignoreNames, className, }: FileTreeViewProps): import("react").JSX.Element;
53
+ export declare const FileTreeView: ForwardRefExoticComponent<FileTreeViewProps & RefAttributes<FileTreeViewHandle>>;
45
54
  export { clampContextMenuPosition };
46
55
  export interface FileTreeRootConfig {
47
56
  filesystem: FilesystemId;
@@ -3,6 +3,18 @@ import { FileTreeNode } from './FileTree';
3
3
  export declare function buildTree(entries: FileEntry[], childrenByDir: Map<string, FileEntry[]>): FileTreeNode[];
4
4
  export declare function parentDir(path: string): string;
5
5
  export declare function dirKey(dir: string): string;
6
+ /**
7
+ * Join a directory and a leaf name into a path, the same way every path in
8
+ * this module is shaped: no leading "./", no doubled or trailing slashes.
9
+ * `dir` is normally "." (root) or a bare relative path like "src/lib" — but
10
+ * some hosts configure a filesystem root as "/" (see company_context in
11
+ * `FileTreeRootConfig`), and naively doing `${dir}/${name}` there produced
12
+ * "//name": a path string that doesn't match what the server round-trips
13
+ * back, so the optimistic entry and the server-confirmed entry never
14
+ * deduped by path and the row rendered twice. Stripping trailing slashes
15
+ * from `dir` first keeps every root shape converging on the same string.
16
+ */
17
+ export declare function joinPath(dir: string, name: string): string;
6
18
  export declare function mergeEntries(base: FileEntry[] | undefined, optimistic: FileEntry[] | undefined): FileEntry[] | undefined;
7
19
  export type DraftEditing = {
8
20
  kind: 'create-file';
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { r as e, t } from "./rolldown-runtime-Dqa2HsxW.js";
2
- import { Mt as n, jt as r, n as i, p as a } from "./WorkspaceProvider-DH-yiJZ8.js";
2
+ import { Mt as n, jt as r, n as i, p as a } from "./WorkspaceProvider-C8rWNm72.js";
3
3
  import { bootClean as o, openPaneViaBridge as s, openWorkbench as c } from "./testing-e2e.js";
4
4
  import * as l from "react";
5
5
  import { cloneElement as u, createElement as d, isValidElement as f, useLayoutEffect as p, useMemo as m, useSyncExternalStore as h } from "react";
@@ -6028,7 +6028,6 @@
6028
6028
  --tracking-widest: 0.1em;
6029
6029
  --leading-snug: 1.375;
6030
6030
  --radius-xs: 0.125rem;
6031
- --ease-out: cubic-bezier(0, 0, 0.2, 1);
6032
6031
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
6033
6032
  --animate-spin: spin 1s linear infinite;
6034
6033
  --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
@@ -6172,6 +6171,9 @@
6172
6171
  .grid {
6173
6172
  display: grid;
6174
6173
  }
6174
+ .inline {
6175
+ display: inline;
6176
+ }
6175
6177
  .inline-block {
6176
6178
  display: inline-block;
6177
6179
  }
@@ -6714,9 +6716,6 @@
6714
6716
  .bg-\[color\:var\(--boring-success-soft\,var\(--secondary\)\)\] {
6715
6717
  background-color: var(--boring-success-soft,var(--secondary));
6716
6718
  }
6717
- .bg-\[color\:var\(--boring-warning\,var\(--accent-foreground\)\)\] {
6718
- background-color: var(--boring-warning,var(--accent-foreground));
6719
- }
6720
6719
  .bg-\[color\:var\(--boring-warning-soft\,var\(--accent\)\)\] {
6721
6720
  background-color: var(--boring-warning-soft,var(--accent));
6722
6721
  }
@@ -7134,11 +7133,6 @@
7134
7133
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
7135
7134
  transition-duration: var(--tw-duration, var(--default-transition-duration));
7136
7135
  }
7137
- .transition-\[width\] {
7138
- transition-property: width;
7139
- transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
7140
- transition-duration: var(--tw-duration, var(--default-transition-duration));
7141
- }
7142
7136
  .transition-all {
7143
7137
  transition-property: all;
7144
7138
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@@ -7175,18 +7169,10 @@
7175
7169
  --tw-duration: 200ms;
7176
7170
  transition-duration: 200ms;
7177
7171
  }
7178
- .duration-300 {
7179
- --tw-duration: 300ms;
7180
- transition-duration: 300ms;
7181
- }
7182
7172
  .ease-in-out {
7183
7173
  --tw-ease: var(--ease-in-out);
7184
7174
  transition-timing-function: var(--ease-in-out);
7185
7175
  }
7186
- .ease-out {
7187
- --tw-ease: var(--ease-out);
7188
- transition-timing-function: var(--ease-out);
7189
- }
7190
7176
  .outline-none {
7191
7177
  --tw-outline-style: none;
7192
7178
  outline-style: none;
@@ -8444,6 +8430,64 @@
8444
8430
  height: calc(var(--spacing) * 4);
8445
8431
  }
8446
8432
  }
8433
+ .\[\&\:\:-moz-progress-bar\]\:rounded-full {
8434
+ &::-moz-progress-bar {
8435
+ border-radius: calc(infinity * 1px);
8436
+ }
8437
+ }
8438
+ .\[\&\:\:-moz-progress-bar\]\:bg-\[color\:var\(--boring-warning\,var\(--accent-foreground\)\)\] {
8439
+ &::-moz-progress-bar {
8440
+ background-color: var(--boring-warning,var(--accent-foreground));
8441
+ }
8442
+ }
8443
+ .\[\&\:\:-moz-progress-bar\]\:bg-destructive {
8444
+ &::-moz-progress-bar {
8445
+ background-color: var(--boring-destructive);
8446
+ }
8447
+ }
8448
+ .\[\&\:\:-moz-progress-bar\]\:bg-primary {
8449
+ &::-moz-progress-bar {
8450
+ background-color: var(--boring-primary);
8451
+ }
8452
+ }
8453
+ .\[\&\:\:-webkit-progress-bar\]\:bg-muted {
8454
+ &::-webkit-progress-bar {
8455
+ background-color: var(--boring-muted);
8456
+ }
8457
+ }
8458
+ .\[\&\:\:-webkit-progress-value\]\:rounded-full {
8459
+ &::-webkit-progress-value {
8460
+ border-radius: calc(infinity * 1px);
8461
+ }
8462
+ }
8463
+ .\[\&\:\:-webkit-progress-value\]\:bg-\[color\:var\(--boring-warning\,var\(--accent-foreground\)\)\] {
8464
+ &::-webkit-progress-value {
8465
+ background-color: var(--boring-warning,var(--accent-foreground));
8466
+ }
8467
+ }
8468
+ .\[\&\:\:-webkit-progress-value\]\:bg-destructive {
8469
+ &::-webkit-progress-value {
8470
+ background-color: var(--boring-destructive);
8471
+ }
8472
+ }
8473
+ .\[\&\:\:-webkit-progress-value\]\:bg-primary {
8474
+ &::-webkit-progress-value {
8475
+ background-color: var(--boring-primary);
8476
+ }
8477
+ }
8478
+ .\[\&\:\:-webkit-progress-value\]\:transition-all {
8479
+ &::-webkit-progress-value {
8480
+ transition-property: all;
8481
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
8482
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
8483
+ }
8484
+ }
8485
+ .\[\&\:\:-webkit-progress-value\]\:duration-300 {
8486
+ &::-webkit-progress-value {
8487
+ --tw-duration: 300ms;
8488
+ transition-duration: 300ms;
8489
+ }
8490
+ }
8447
8491
  .\[\&\:\:-webkit-scrollbar\]\:hidden {
8448
8492
  &::-webkit-scrollbar {
8449
8493
  display: none;
package/dist/workspace.js CHANGED
@@ -1,8 +1,8 @@
1
- import { $ as e, $t as t, A as n, At as r, Bt as i, Ct as a, D as o, Dt as s, E as c, Et as l, Ft as u, Gt as d, Ht as f, It as p, J as m, Jt as h, K as g, Lt as _, Mt as v, Nt as y, O as b, Ot as x, Pt as S, Q as C, Qt as w, Rt as T, S as ee, Sn as te, St as ne, T as re, Tt as E, U as ie, Ut as ae, Vt as oe, W as se, Wt as ce, Xt as le, Y as ue, Yt as de, Z as fe, Zt as pe, _n as me, _t as he, a as ge, an as _e, at as ve, b as ye, bn as be, bt as xe, cn as Se, ct as Ce, d as we, dn as D, dt as O, en as k, et as Te, f as Ee, fn as De, ft as Oe, gn as ke, gt as A, h as Ae, hn as je, ht as Me, i as Ne, in as Pe, it as Fe, jt as Ie, k as Le, l as Re, ln as ze, lt as Be, mn as j, mt as Ve, n as He, nt as Ue, o as We, on as Ge, ot as Ke, p as qe, pn as Je, pt as Ye, q as Xe, qt as Ze, r as Qe, rn as $e, rt as et, s as tt, sn as nt, st as rt, t as it, tn as at, tt as ot, u as st, un as ct, ut as lt, vn as ut, vt as dt, w as ft, wt as pt, x as mt, xt as ht, y as gt, yn as _t, yt as vt, zt as yt } from "./WorkspaceProvider-DH-yiJZ8.js";
2
- import { t as bt } from "./MarkdownEditor-D8NqIunl.js";
1
+ import { $ as e, $t as t, A as n, At as r, Bt as i, Ct as a, D as o, Dt as s, E as c, Et as l, Ft as u, Gt as d, Ht as f, It as p, J as m, Jt as h, K as g, Lt as _, Mt as v, Nt as y, O as b, Ot as x, Pt as S, Q as C, Qt as w, Rt as T, S as ee, Sn as te, St as ne, T as re, Tt as E, U as ie, Ut as ae, Vt as oe, W as se, Wt as ce, Xt as le, Y as ue, Yt as de, Z as fe, Zt as pe, _n as me, _t as he, a as ge, an as _e, at as ve, b as ye, bn as be, bt as xe, cn as Se, ct as Ce, d as we, dn as D, dt as O, en as k, et as Te, f as Ee, fn as De, ft as Oe, gn as ke, gt as A, h as Ae, hn as je, ht as Me, i as Ne, in as Pe, it as Fe, jt as Ie, k as Le, l as Re, ln as ze, lt as Be, mn as j, mt as Ve, n as He, nt as Ue, o as We, on as Ge, ot as Ke, p as qe, pn as Je, pt as Ye, q as Xe, qt as Ze, r as Qe, rn as $e, rt as et, s as tt, sn as nt, st as rt, t as it, tn as at, tt as ot, u as st, un as ct, ut as lt, vn as ut, vt as dt, w as ft, wt as pt, x as mt, xt as ht, y as gt, yn as _t, yt as vt, zt as yt } from "./WorkspaceProvider-C8rWNm72.js";
2
+ import { t as bt } from "./MarkdownEditor-B4MXLBVy.js";
3
3
  import { t as M } from "./utils-BRcxFdrz.js";
4
- import { d as xt, i as St, n as Ct, p as wt, r as Tt, t as Et } from "./WorkspaceLoadingState-D_b8t-6U.js";
5
- import { t as Dt } from "./FileTree-DQQ1NXtr.js";
4
+ import { d as xt, i as St, n as Ct, p as wt, r as Tt, t as Et } from "./WorkspaceLoadingState-BkAUFt_A.js";
5
+ import { t as Dt } from "./FileTree-BIRGkW6O.js";
6
6
  import { Component as Ot, Suspense as kt, useCallback as N, useEffect as P, useMemo as F, useRef as I, useState as L, useSyncExternalStore as R } from "react";
7
7
  import { Fragment as At, jsx as z, jsxs as B } from "react/jsx-runtime";
8
8
  import { CheckIcon as jt, CopyIcon as Mt, MenuIcon as Nt, PanelLeftIcon as V, PinIcon as Pt } from "lucide-react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-workspace",
3
- "version": "0.1.82",
3
+ "version": "0.1.84",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Workspace UI, plugin, and bridge package for composing chat, files, catalogs, editors, and app-specific panes.",
@@ -139,9 +139,9 @@
139
139
  "tailwind-merge": "^2.0.0",
140
140
  "zod": "^3.23.0",
141
141
  "zustand": "^5.0.14",
142
- "@hachej/boring-agent": "0.1.82",
143
- "@hachej/boring-ui-plugin-cli": "0.1.82",
144
- "@hachej/boring-ui-kit": "0.1.82"
142
+ "@hachej/boring-agent": "0.1.84",
143
+ "@hachej/boring-ui-kit": "0.1.84",
144
+ "@hachej/boring-ui-plugin-cli": "0.1.84"
145
145
  },
146
146
  "devDependencies": {
147
147
  "@tailwindcss/postcss": "^4.3.1",